summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HACKING46
-rw-r--r--HACKING.pending15
-rwxr-xr-xREADME.NetBSD4
-rw-r--r--bgpd/bgp_aspath.c118
-rw-r--r--bgpd/bgp_aspath.h2
-rw-r--r--bgpd/bgp_attr.c287
-rw-r--r--bgpd/bgp_attr.h6
-rw-r--r--bgpd/bgp_damp.c6
-rw-r--r--bgpd/bgp_debug.c7
-rw-r--r--bgpd/bgp_dump.c4
-rw-r--r--bgpd/bgp_main.c10
-rw-r--r--bgpd/bgp_network.c20
-rw-r--r--bgpd/bgp_nexthop.c22
-rw-r--r--bgpd/bgp_open.h8
-rw-r--r--bgpd/bgp_packet.c140
-rw-r--r--bgpd/bgp_route.c1621
-rw-r--r--bgpd/bgp_route.h3
-rw-r--r--bgpd/bgp_routemap.c128
-rw-r--r--bgpd/bgp_table.c1
-rw-r--r--bgpd/bgp_vty.c225
-rw-r--r--bgpd/bgpd.c173
-rw-r--r--bgpd/bgpd.h8
-rwxr-xr-xconfigure.ac15
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/bgpd.texi23
-rw-r--r--doc/main.texi4
-rw-r--r--doc/routemap.texi14
-rw-r--r--lib/command.c4
-rw-r--r--lib/distribute.c13
-rw-r--r--lib/hash.c11
-rw-r--r--lib/hash.h2
-rw-r--r--lib/if.c20
-rw-r--r--lib/if.h1
-rw-r--r--lib/if_rmap.c9
-rw-r--r--lib/log.c3
-rw-r--r--lib/memory.c42
-rw-r--r--lib/memtypes.c1
-rw-r--r--lib/prefix.c13
-rw-r--r--lib/prefix.h4
-rw-r--r--lib/sockunion.c40
-rw-r--r--lib/sockunion.h2
-rw-r--r--lib/table.c14
-rw-r--r--lib/thread.c142
-rw-r--r--lib/thread.h3
-rw-r--r--lib/vty.c2
-rw-r--r--lib/workqueue.c17
-rw-r--r--lib/zclient.c6
-rw-r--r--ospf6d/ospf6_area.c6
-rw-r--r--ospf6d/ospf6_asbr.c5
-rw-r--r--ospf6d/ospf6_asbr.h1
-rw-r--r--ospf6d/ospf6_interface.c58
-rw-r--r--ospf6d/ospf6_interface.h3
-rw-r--r--ospf6d/ospf6_intra.c2
-rw-r--r--ospf6d/ospf6_lsa.c5
-rw-r--r--ospf6d/ospf6_lsa.h1
-rw-r--r--ospf6d/ospf6_main.c35
-rw-r--r--ospf6d/ospf6_message.c20
-rw-r--r--ospf6d/ospf6_message.h1
-rw-r--r--ospf6d/ospf6_route.c15
-rw-r--r--ospf6d/ospf6_spf.c35
-rw-r--r--ospf6d/ospf6_top.c9
-rw-r--r--ospf6d/ospf6_top.h1
-rw-r--r--ospf6d/ospf6_zebra.c3
-rw-r--r--ospfd/ospf_abr.c7
-rw-r--r--ospfd/ospf_api.c2
-rw-r--r--ospfd/ospf_apiserver.c4
-rw-r--r--ospfd/ospf_apiserver.h2
-rw-r--r--ospfd/ospf_asbr.c3
-rw-r--r--ospfd/ospf_ase.c12
-rw-r--r--ospfd/ospf_flood.c34
-rw-r--r--ospfd/ospf_flood.h1
-rw-r--r--ospfd/ospf_interface.c20
-rw-r--r--ospfd/ospf_interface.h6
-rw-r--r--ospfd/ospf_ism.c17
-rw-r--r--ospfd/ospf_lsa.c351
-rw-r--r--ospfd/ospf_lsa.h24
-rw-r--r--ospfd/ospf_lsdb.c15
-rw-r--r--ospfd/ospf_network.c14
-rw-r--r--ospfd/ospf_nsm.c33
-rw-r--r--ospfd/ospf_nsm.h2
-rw-r--r--ospfd/ospf_opaque.c17
-rw-r--r--ospfd/ospf_opaque.h4
-rw-r--r--ospfd/ospf_packet.c116
-rw-r--r--ospfd/ospf_packet.h1
-rw-r--r--ospfd/ospf_te.c6
-rw-r--r--ospfd/ospf_vty.c14
-rw-r--r--ospfd/ospfd.c15
-rw-r--r--ospfd/ospfd.h9
-rw-r--r--ripd/rip_debug.c24
-rw-r--r--ripd/rip_debug.h1
-rw-r--r--ripngd/ripng_debug.c26
-rw-r--r--ripngd/ripng_debug.h2
-rw-r--r--tests/aspath_test.c2
-rw-r--r--zebra/zebra_routemap.c11
-rw-r--r--zebra/zserv.c2
95 files changed, 2765 insertions, 1493 deletions
diff --git a/HACKING b/HACKING
index 5a207274..0358fed2 100644
--- a/HACKING
+++ b/HACKING
@@ -17,6 +17,7 @@ Contents:
* STABLE PLATFORMS AND DAEMONS
* IMPORT OR UPDATE VENDOR SPECIFIC ROUTING PROTOCOLS
+
GUIDELINES FOR HACKING ON QUAGGA
[this is a draft in progress]
@@ -98,6 +99,7 @@ release.
See also below regarding SHARED LIBRARY VERSIONING.
+
COMPILE-TIME CONDITIONAL CODE
Please think very carefully before making code conditional at compile time,
@@ -121,12 +123,13 @@ rather than:
Note that the former approach requires ensuring that SOME_SYMBOL will be
defined (watch your AC_DEFINEs).
+
COMMIT MESSAGES
The commit message should provide:
-* A suitable one-line summary as the very first line of the message, in the
- form:
+* A suitable one-line summary followed by a blank line as the very
+ first line of the message, in the form:
topic: high-level, one line summary
@@ -141,12 +144,14 @@ The commit message should provide:
to provide a short description of the general intent of the patch, in terms
of the problem it solves and how it achieves it, to help reviewers
-understand.
+understand.
+The one-line summary must be limited to 54 characters, and all other
+lines to 72 characters.
The reason for such itemised commit messages is to encourage the author to
self-review every line of the patch, as well as provide reviewers an index
-of which changes are intended, along with a short description for each.
+of which changes are intended, along with a short description for each.
Some discretion is obviously required. A C-to-english description is not
desireable. For short patches, a per-function/file break-down may be
redundant. For longer patches, such a break-down may be essential.
@@ -157,11 +162,13 @@ given the one-line summary):
zebra: Enhance frob FSM to detect loss of frob
* (general) Add a new DOWN state to the frob state machine
- to allow the barinator to detect loss of frob.
+ to allow the barinator to detect loss of frob.
* frob.h: (struct frob) Add DOWN state flag.
* frob.c: (frob_change) set/clear DOWN appropriately on state change.
* bar.c: (barinate) Check frob for DOWN state.
+Note that the commit message format follows git norms, so that "git
+log --oneline" will have useful output.
HACKING THE BUILD SYSTEM
@@ -170,13 +177,14 @@ etc.), try to check that the following things still work:
- make dist
- resulting dist tarball builds
- - out-of-tree builds
+ - out-of-tree builds
The quagga.net site relies on make dist to work to generate snapshots. It
must work. Common problems are to forget to have some additional file
included in the dist, or to have a make rule refer to a source file without
using the srcdir variable.
+
RELEASE PROCEDURE
* Tag the apppropriate commit with a release tag (follow existing
@@ -199,7 +207,7 @@ RELEASE PROCEDURE
The tarball which 'make dist' creates is the tarball to be released! The
git-archive step ensures you're working with code corresponding to that in
the official repository, and also carries out keyword expansion. If any
-errors occur, move tags as needed and start over from the fresh checkouts.
+errors occur, move tags as needed and start over from the fresh checkouts.
Do not append to tarballs, as this has produced non-standards-conforming
tarballs in the past.
@@ -239,23 +247,33 @@ library libzebra and the included daemons should always be built and
installed together.
+GIT COMMIT SUBSMISSION
+
+The preferred method for changes is to provide git commits via a
+publically-accessible git repository.
+
+All content guidelines in PATCH SUBMISSION apply.
+
+
PATCH SUBMISSION
* Send a clean diff against the 'master' branch of the quagga.git
- repository, in unified diff format, preferably with the '-p' argument to
+ repository, in unified diff format, preferably with the '-p' argument to
show C function affected by any chunk, and with the -w and -b arguments to
- minimise changes. E.g:
+ minimise changes. E.g:
git diff -up mybranch..remotes/quagga.net/master
- Or by using git-format-patch.
+ It is preferable to use git format-patch, and even more preferred to
+ publish a git repostory.
-* Not doing so is a definite hindrance to patch application.
+ If not using git format-patch, Include the commit message in the email.
-* Include NEWS entries as appropriate.
+* After a commit, code should have comments explaining to the reviewer
+ why it is correct, without reference to history. The commit message
+ should explain why the change is correct.
-* Please, please include an appropriate commit message with any emailed
- patches. Doing so makes it easier to review a patch, and apply it.
+* Include NEWS entries as appropriate.
* Include only one semantic change or group of changes per patch.
diff --git a/HACKING.pending b/HACKING.pending
index 3b923a41..5e0defd8 100644
--- a/HACKING.pending
+++ b/HACKING.pending
@@ -19,8 +19,21 @@ collected in his git repository.
This repository has topic branches for patches intended for inclusion
in the main quagga tree, named patches/, plus some other branches.
+** git remote add balajig http://github.com/balajig/quagga-next.git
+
+Balaji G has prepared a git repository where a number of patches to
+the list have been stored.
+
+** git remote add mtr http://github.com/tomhenderson/quagga-mtr.git
+
+Tom Henderson of Boeing has created a repository to work on
+multi-topology routing support for OSPF. Work on this repository
+takes place on the branch mtr, which has a branch point of 0.99.17
+
* posted patches
+** Boeing
+
Boeing has posted patches
quagga-0.99.9.ospfv3-addressfamilies.patch
@@ -32,3 +45,5 @@ against 0.99.9 at
Both patches include functional enhancements as well as support for
gcc 2.95.
+
+[TODO: Are any of these obsolete with respect to mtr/mtr?]
diff --git a/README.NetBSD b/README.NetBSD
index 9aac4c35..6bbc680b 100755
--- a/README.NetBSD
+++ b/README.NetBSD
@@ -20,13 +20,15 @@ PREFIX=/usr/pkg
case $1 in
build)
+ # Omitted because it is now default:
+ # --enable-opaque-lsa
./bootstrap.sh
LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" CPPFLAGS="-I/usr/pkg/include" \
./configure --prefix=${PREFIX} \
--sysconfdir=/etc/zebra --localstatedir=/var/run/zebra \
--enable-exampledir=${PREFIX}/share/examples/zebra \
--enable-pkgsrcrcdir=${PREFIX}/etc/rc.d \
- --enable-opaque-lsa --enable-vtysh
+ --enable-vtysh
${MAKE}
;;
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index a9602d90..cf930427 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -671,58 +671,80 @@ aspath_hash_alloc (void *arg)
return aspath;
}
-/* parse as-segment byte stream in struct assegment */
+/* parse as-segment byte stream in struct assegment
+ *
+ * Returns NULL if the AS_PATH or AS4_PATH is not valid.
+ */
static struct assegment *
-assegments_parse (struct stream *s, size_t length, int use32bit)
+assegments_parse (struct stream *s, size_t length, int use32bit, int as4_path)
{
struct assegment_header segh;
struct assegment *seg, *prev = NULL, *head = NULL;
- size_t bytes = 0;
- /* empty aspath (ie iBGP or somesuch) */
- if (length == 0)
- return NULL;
+ assert (length > 0); /* does not expect empty AS_PATH or AS4_PATH */
if (BGP_DEBUG (as4, AS4_SEGMENT))
zlog_debug ("[AS4SEG] Parse aspath segment: got total byte length %lu",
(unsigned long) length);
- /* basic checks */
- if ( (STREAM_READABLE(s) < length)
- || (STREAM_READABLE(s) < AS_HEADER_SIZE)
- || (length % AS16_VALUE_SIZE ))
+
+ /* double check that length does not exceed stream */
+ if (STREAM_READABLE(s) < length)
return NULL;
- while ( (STREAM_READABLE(s) > AS_HEADER_SIZE)
- && (bytes < length))
+ /* deal with each segment in turn */
+ while (length > 0)
{
int i;
- int seg_size;
+ size_t seg_size;
/* softly softly, get the header first on its own */
+ if (length < AS_HEADER_SIZE)
+ {
+ assegment_free_all (head);
+ return NULL;
+ }
+
segh.type = stream_getc (s);
segh.length = stream_getc (s);
seg_size = ASSEGMENT_SIZE(segh.length, use32bit);
+ /* includes the header bytes */
if (BGP_DEBUG (as4, AS4_SEGMENT))
zlog_debug ("[AS4SEG] Parse aspath segment: got type %d, length %d",
segh.type, segh.length);
- /* check it.. */
- if ( ((bytes + seg_size) > length)
- /* 1771bis 4.3b: seg length contains one or more */
- || (segh.length == 0)
- /* Paranoia in case someone changes type of segment length.
- * Shift both values by 0x10 to make the comparison operate
- * on more, than 8 bits (otherwise it's a warning, bug #564).
+ switch (segh.type)
+ {
+ case AS_SEQUENCE:
+ case AS_SET:
+ break ;
+
+ case AS_CONFED_SEQUENCE:
+ case AS_CONFED_SET:
+ if (!as4_path)
+ break ;
+ /* RFC4893 3: "invalid for the AS4_PATH attribute" */
+ /* fall through */
+
+ default: /* reject unknown or invalid AS_PATH segment types */
+ seg_size = 0 ;
+ }
+
+ /* Stop now if segment is not valid (discarding anything collected to date)
+ *
+ * RFC4271 4.3, Path Attributes, b) AS_PATH:
+ *
+ * "path segment value field contains one or more AS numbers"
*/
- || ((sizeof segh.length > 1) && (0x10 + segh.length > 0x10 + AS_SEGMENT_MAX)) )
+ if ((seg_size == 0) || (seg_size > length) || (segh.length == 0))
{
- if (head)
- assegment_free_all (head);
+ assegment_free_all (head);
return NULL;
}
+ length -= seg_size ;
+
/* now its safe to trust lengths */
seg = assegment_new (segh.type, segh.length);
@@ -734,11 +756,9 @@ assegments_parse (struct stream *s, size_t length, int use32bit)
for (i = 0; i < segh.length; i++)
seg->as[i] = (use32bit) ? stream_getl (s) : stream_getw (s);
- bytes += seg_size;
-
if (BGP_DEBUG (as4, AS4_SEGMENT))
- zlog_debug ("[AS4SEG] Parse aspath segment: Bytes now: %lu",
- (unsigned long) bytes);
+ zlog_debug ("[AS4SEG] Parse aspath segment: length left: %lu",
+ (unsigned long) length);
prev = seg;
}
@@ -746,30 +766,42 @@ assegments_parse (struct stream *s, size_t length, int use32bit)
return assegment_normalise (head);
}
-/* AS path parse function. pnt is a pointer to byte stream and length
- is length of byte stream. If there is same AS path in the the AS
- path hash then return it else make new AS path structure. */
+/* AS path parse function -- parses AS_PATH and AS4_PATH attributes
+ *
+ * Requires: s -- stream, currently positioned before first segment
+ * of AS_PATH or AS4_PATH (ie after attribute header)
+ * length -- length of the value of the AS_PATH or AS4_PATH
+ * use32bit -- true <=> 4Byte ASN, otherwise 2Byte ASN
+ * as4_path -- true <=> AS4_PATH, otherwise AS_PATH
+ *
+ * Returns: if valid: address of struct aspath in the hash of known aspaths,
+ * with reference count incremented.
+ * else: NULL
+ *
+ * NB: empty AS path (length == 0) is valid. The returned struct aspath will
+ * have segments == NULL and str == zero length string (unique).
+ */
struct aspath *
-aspath_parse (struct stream *s, size_t length, int use32bit)
+aspath_parse (struct stream *s, size_t length, int use32bit, int as4_path)
{
struct aspath as;
struct aspath *find;
- /* If length is odd it's malformed AS path. */
- /* Nit-picking: if (use32bit == 0) it is malformed if odd,
- * otherwise its malformed when length is larger than 2 and (length-2)
- * is not dividable by 4.
- * But... this time we're lazy
- */
- if (length % AS16_VALUE_SIZE )
- return NULL;
-
+ /* Parse each segment and construct normalised list of struct assegment */
memset (&as, 0, sizeof (struct aspath));
- as.segments = assegments_parse (s, length, use32bit);
+ if (length != 0)
+ {
+ as.segments = assegments_parse (s, length, use32bit, as4_path);
+
+ if (as.segments == NULL)
+ return NULL ; /* Invalid AS_PATH or AS4_PATH */
+ } ;
/* If already same aspath exist then return it. */
find = hash_get (ashash, &as, aspath_hash_alloc);
+ assert(find) ; /* valid aspath, so must find or create */
+
/* aspath_hash_alloc dupes segments too. that probably could be
* optimised out.
*/
@@ -777,8 +809,6 @@ aspath_parse (struct stream *s, size_t length, int use32bit)
if (as.str)
XFREE (MTYPE_AS_STR, as.str);
- if (! find)
- return NULL;
find->refcnt++;
return find;
@@ -1602,7 +1632,7 @@ aspath_segment_add (struct aspath *as, int type)
struct aspath *
aspath_empty (void)
{
- return aspath_parse (NULL, 0, 1); /* 32Bit ;-) */
+ return aspath_parse (NULL, 0, 1, 0); /* 32Bit ;-) not AS4_PATH */
}
struct aspath *
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index b8a5dfab..d63b914c 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -65,7 +65,7 @@ struct aspath
/* Prototypes. */
extern void aspath_init (void);
extern void aspath_finish (void);
-extern struct aspath *aspath_parse (struct stream *, size_t, int);
+extern struct aspath *aspath_parse (struct stream *, size_t, int, int);
extern struct aspath *aspath_dup (struct aspath *);
extern struct aspath *aspath_aggregate (struct aspath *, struct aspath *);
extern struct aspath *aspath_prepend (struct aspath *, struct aspath *);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 5e7536ae..01598c87 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -28,6 +28,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "stream.h"
#include "log.h"
#include "hash.h"
+#include "jhash.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
@@ -116,18 +117,9 @@ cluster_loop_check (struct cluster_list *cluster, struct in_addr originator)
static unsigned int
cluster_hash_key_make (void *p)
{
- struct cluster_list * cluster = (struct cluster_list *) p;
- unsigned int key = 0;
- int length;
- caddr_t pnt;
+ const struct cluster_list *cluster = p;
- length = cluster->length;
- pnt = (caddr_t) cluster->list;
-
- while (length)
- key += pnt[--length];
-
- return key;
+ return jhash(cluster->list, cluster->length, 0);
}
static int
@@ -258,18 +250,9 @@ transit_unintern (struct transit *transit)
static unsigned int
transit_hash_key_make (void *p)
{
- struct transit * transit = (struct transit *) p;
- unsigned int key = 0;
- int length;
- caddr_t pnt;
+ const struct transit * transit = p;
- length = transit->length;
- pnt = (caddr_t) transit->val;
-
- while (length)
- key += pnt[--length];
-
- return key;
+ return jhash(transit->val, transit->length, 0);
}
static int
@@ -352,51 +335,46 @@ attr_unknown_count (void)
unsigned int
attrhash_key_make (void *p)
{
- struct attr * attr = (struct attr *) p;
- unsigned int key = 0;
+ const struct attr * attr = (struct attr *) p;
+ uint32_t key = 0;
+#define MIX(val) key = jhash_1word(val, key)
+
+ MIX(attr->origin);
+ MIX(attr->nexthop.s_addr);
+ MIX(attr->med);
+ MIX(attr->local_pref);
key += attr->origin;
key += attr->nexthop.s_addr;
key += attr->med;
key += attr->local_pref;
- if (attr->pathlimit.as)
- {
- key += attr->pathlimit.ttl;
- key += attr->pathlimit.as;
- }
if (attr->extra)
{
- key += attr->extra->aggregator_as;
- key += attr->extra->aggregator_addr.s_addr;
- key += attr->extra->weight;
- key += attr->extra->mp_nexthop_global_in.s_addr;
+ MIX(attr->extra->aggregator_as);
+ MIX(attr->extra->aggregator_addr.s_addr);
+ MIX(attr->extra->weight);
+ MIX(attr->extra->mp_nexthop_global_in.s_addr);
}
if (attr->aspath)
- key += aspath_key_make (attr->aspath);
+ MIX(aspath_key_make (attr->aspath));
if (attr->community)
- key += community_hash_make (attr->community);
+ MIX(community_hash_make (attr->community));
if (attr->extra)
{
if (attr->extra->ecommunity)
- key += ecommunity_hash_make (attr->extra->ecommunity);
+ MIX(ecommunity_hash_make (attr->extra->ecommunity));
if (attr->extra->cluster)
- key += cluster_hash_key_make (attr->extra->cluster);
+ MIX(cluster_hash_key_make (attr->extra->cluster));
if (attr->extra->transit)
- key += transit_hash_key_make (attr->extra->transit);
+ MIX(transit_hash_key_make (attr->extra->transit));
#ifdef HAVE_IPV6
- {
- int i;
-
- key += attr->extra->mp_nexthop_len;
- for (i = 0; i < 16; i++)
- key += attr->extra->mp_nexthop_global.s6_addr[i];
- for (i = 0; i < 16; i++)
- key += attr->extra->mp_nexthop_local.s6_addr[i];
- }
+ MIX(attr->extra->mp_nexthop_len);
+ key = jhash(attr->extra->mp_nexthop_global.s6_addr, 16, key);
+ key = jhash(attr->extra->mp_nexthop_local.s6_addr, 16, key);
#endif /* HAVE_IPV6 */
}
@@ -415,9 +393,7 @@ attrhash_cmp (const void *p1, const void *p2)
&& attr1->aspath == attr2->aspath
&& attr1->community == attr2->community
&& attr1->med == attr2->med
- && attr1->local_pref == attr2->local_pref
- && attr1->pathlimit.ttl == attr2->pathlimit.ttl
- && attr1->pathlimit.as == attr2->pathlimit.as)
+ && attr1->local_pref == attr2->local_pref)
{
const struct attr_extra *ae1 = attr1->extra;
const struct attr_extra *ae2 = attr2->extra;
@@ -704,43 +680,6 @@ bgp_attr_flush (struct attr *attr)
}
}
-/* Parse AS_PATHLIMIT attribute in an UPDATE */
-static int
-bgp_attr_aspathlimit (struct peer *peer, bgp_size_t length,
- struct attr *attr, u_char flag, u_char *startp)
-{
- bgp_size_t total;
-
- total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
-
- if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
- || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
- {
- zlog (peer->log, LOG_ERR,
- "AS-Pathlimit attribute flag isn't transitive %d", flag);
- bgp_notify_send_with_data (peer,
- BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
- startp, total);
- return -1;
- }
-
- if (length != 5)
- {
- zlog (peer->log, LOG_ERR,
- "AS-Pathlimit length, %u, is not 5", length);
- bgp_notify_send_with_data (peer,
- BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
- startp, total);
- return -1;
- }
-
- attr->pathlimit.ttl = stream_getc (BGP_INPUT(peer));
- attr->pathlimit.as = stream_getl (BGP_INPUT(peer));
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
- return 0;
-}
/* Get origin attribute of the update message. */
static int
bgp_attr_origin (struct peer *peer, bgp_size_t length,
@@ -807,54 +746,78 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length,
return 0;
}
-
-/* Parse AS path information. This function is wrapper of
- aspath_parse. */
-static int
+/* Parse AS path information. This function is wrapper of aspath_parse.
+ *
+ * Parses AS_PATH or AS4_PATH.
+ *
+ * Returns: if valid: address of struct aspath in the hash of known aspaths,
+ * with reference count incremented.
+ * else: NULL
+ *
+ * NB: empty AS path (length == 0) is valid. The returned struct aspath will
+ * have segments == NULL and str == zero length string (unique).
+ */
+static struct aspath *
bgp_attr_aspath (struct peer *peer, bgp_size_t length,
- struct attr *attr, u_char flag, u_char *startp)
+ struct attr *attr, u_char flag, u_char *startp, int as4_path)
{
- bgp_size_t total;
+ u_char require ;
+ struct aspath *asp ;
- total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+ /* Check the attribute flags */
+ require = as4_path ? BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
+ : BGP_ATTR_FLAG_TRANS ;
- /* Flag check. */
- if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)
- || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
+ if ((flag & (BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS)) != require)
{
+ const char* path_type ;
+ bgp_size_t total;
+
+ path_type = as4_path ? "AS4_PATH" : "AS_PATH" ;
+
+ if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
zlog (peer->log, LOG_ERR,
- "As-Path attribute flag isn't transitive %d", flag);
+ "%s attribute flag isn't transitive %d", path_type, flag) ;
+
+ if ((flag & BGP_ATTR_FLAG_OPTIONAL) != (require & BGP_ATTR_FLAG_OPTIONAL))
+ zlog (peer->log, LOG_ERR,
+ "%s attribute flag must %sbe optional %d", path_type,
+ (flag & BGP_ATTR_FLAG_OPTIONAL) ? "not " : "", flag) ;
+
+ total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total);
- return -1;
- }
- /*
- * peer with AS4 => will get 4Byte ASnums
- * otherwise, will get 16 Bit
+ return NULL ;
+ } ;
+
+ /* Parse the AS_PATH/AS4_PATH body.
+ *
+ * For AS_PATH peer with AS4 => 4Byte ASN otherwise 2Byte ASN
+ * AS4_PATH 4Byte ASN
*/
- attr->aspath = aspath_parse (peer->ibuf, length,
- CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV));
+ asp = aspath_parse (peer->ibuf, length,
+ as4_path || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV), as4_path) ;
- /* In case of IBGP, length will be zero. */
- if (! attr->aspath)
+ if (asp != NULL)
+ {
+ attr->flag |= ATTR_FLAG_BIT (as4_path ? BGP_ATTR_AS4_PATH
+ : BGP_ATTR_AS_PATH) ;
+ }
+ else
{
zlog (peer->log, LOG_ERR, "Malformed AS path length is %d", length);
+
+ /* TODO: should BGP_NOTIFY_UPDATE_MAL_AS_PATH be sent for AS4_PATH ?? */
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_AS_PATH);
- return -1;
- }
-
- /* Forward pointer. */
-/* stream_forward_getp (peer->ibuf, length);*/
-
- /* Set aspath attribute flag. */
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
+ } ;
- return 0;
+ return asp ;
}
static int bgp_attr_aspath_check( struct peer *peer,
@@ -912,21 +875,6 @@ static int bgp_attr_aspath_check( struct peer *peer,
}
-/* Parse AS4 path information. This function is another wrapper of
- aspath_parse. */
-static int
-bgp_attr_as4_path (struct peer *peer, bgp_size_t length,
- struct attr *attr, struct aspath **as4_path)
-{
- *as4_path = aspath_parse (peer->ibuf, length, 1);
-
- /* Set aspath attribute flag. */
- if (as4_path)
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
-
- return 0;
-}
-
/* Nexthop attribute. */
static int
bgp_attr_nexthop (struct peer *peer, bgp_size_t length,
@@ -1226,13 +1174,16 @@ bgp_attr_community (struct peer *peer, bgp_size_t length,
attr->community = NULL;
return 0;
}
- else
- {
- attr->community =
- community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
- stream_forward_getp (peer->ibuf, length);
- }
+
+ attr->community =
+ community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
+
+ /* XXX: fix community_parse to use stream API and remove this */
+ stream_forward_getp (peer->ibuf, length);
+ if (!attr->community)
+ return -1;
+
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
return 0;
@@ -1292,8 +1243,8 @@ int
bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
struct bgp_nlri *mp_update)
{
- u_int16_t afi;
- u_char safi;
+ afi_t afi;
+ safi_t safi;
bgp_size_t nlri_len;
size_t start;
int ret;
@@ -1427,8 +1378,8 @@ bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length,
struct bgp_nlri *mp_withdraw)
{
struct stream *s;
- u_int16_t afi;
- u_char safi;
+ afi_t afi;
+ safi_t safi;
u_int16_t withdraw_len;
int ret;
@@ -1469,13 +1420,18 @@ bgp_attr_ext_communities (struct peer *peer, bgp_size_t length,
{
if (attr->extra)
attr->extra->ecommunity = NULL;
+ /* Empty extcomm doesn't seem to be invalid per se */
+ return 0;
}
- else
- {
- (bgp_attr_extra_get (attr))->ecommunity =
- ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
- stream_forward_getp (peer->ibuf, length);
- }
+
+ (bgp_attr_extra_get (attr))->ecommunity =
+ ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
+ /* XXX: fix ecommunity_parse to use stream API */
+ stream_forward_getp (peer->ibuf, length);
+
+ if (!attr->extra->ecommunity)
+ return -1;
+
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
return 0;
@@ -1657,10 +1613,12 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
ret = bgp_attr_origin (peer, length, attr, flag, startp);
break;
case BGP_ATTR_AS_PATH:
- ret = bgp_attr_aspath (peer, length, attr, flag, startp);
+ attr->aspath = bgp_attr_aspath (peer, length, attr, flag, startp, 0);
+ ret = attr->aspath ? 0 : -1 ;
break;
case BGP_ATTR_AS4_PATH:
- ret = bgp_attr_as4_path (peer, length, attr, &as4_path );
+ as4_path = bgp_attr_aspath (peer, length, attr, flag, startp, 1);
+ ret = as4_path ? 0 : -1 ;
break;
case BGP_ATTR_NEXT_HOP:
ret = bgp_attr_nexthop (peer, length, attr, flag, startp);
@@ -1698,9 +1656,6 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
case BGP_ATTR_EXT_COMMUNITIES:
ret = bgp_attr_ext_communities (peer, length, attr, flag);
break;
- case BGP_ATTR_AS_PATHLIMIT:
- ret = bgp_attr_aspathlimit (peer, length, attr, flag, startp);
- break;
default:
ret = bgp_attr_unknown (peer, attr, flag, type, length, startp);
break;
@@ -2255,24 +2210,6 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
}
- /* AS-Pathlimit */
- if (attr->pathlimit.ttl)
- {
- u_int32_t as = attr->pathlimit.as;
-
- /* should already have been done in announce_check(),
- * but just in case..
- */
- if (!as)
- as = peer->local_as;
-
- stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
- stream_putc (s, BGP_ATTR_AS_PATHLIMIT);
- stream_putc (s, 5);
- stream_putc (s, attr->pathlimit.ttl);
- stream_putl (s, as);
- }
-
/* Unknown transit attribute. */
if (attr->extra && attr->extra->transit)
stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
@@ -2484,16 +2421,6 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr,
}
#endif /* HAVE_IPV6 */
- /* AS-Pathlimit */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT))
- {
- stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
- stream_putc (s, BGP_ATTR_AS_PATHLIMIT);
- stream_putc (s, 5);
- stream_putc (s, attr->pathlimit.ttl);
- stream_putl (s, attr->pathlimit.as);
- }
-
/* Return total size of attribute. */
len = stream_get_endp (s) - cp - 2;
stream_putw_at (s, cp, len);
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index ed8753bd..af9dcf5e 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -110,12 +110,6 @@ struct attr
u_int32_t med;
u_int32_t local_pref;
- /* AS-Pathlimit */
- struct {
- u_int32_t as;
- u_char ttl;
- } pathlimit;
-
/* Path origin attribute */
u_char origin;
};
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index ba059f8c..a5138833 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -407,14 +407,10 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
damp->reuse_list_size
* sizeof (struct bgp_reuse_node *));
- memset (damp->reuse_list, 0x00,
- damp->reuse_list_size * sizeof (struct bgp_reuse_node *));
/* Reuse-array computations */
- damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
+ damp->reuse_index = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * damp->reuse_index_size);
- memset (damp->reuse_index, 0x00,
- damp->reuse_list_size * sizeof (int));
reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit;
j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0));
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index c2077a59..26b35dfc 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -331,7 +331,6 @@ ALIAS (no_debug_bgp_as4,
undebug_bgp_as4_cmd,
"undebug bgp as4",
UNDEBUG_STR
- DEBUG_STR
BGP_STR
"BGP AS4 actions\n")
@@ -340,6 +339,7 @@ DEFUN (debug_bgp_as4_segment,
"debug bgp as4 segment",
DEBUG_STR
BGP_STR
+ "BGP AS4 actions\n"
"BGP AS4 aspath segment handling\n")
{
if (vty->node == CONFIG_NODE)
@@ -358,6 +358,7 @@ DEFUN (no_debug_bgp_as4_segment,
NO_STR
DEBUG_STR
BGP_STR
+ "BGP AS4 actions\n"
"BGP AS4 aspath segment handling\n")
{
if (vty->node == CONFIG_NODE)
@@ -374,8 +375,8 @@ ALIAS (no_debug_bgp_as4_segment,
undebug_bgp_as4_segment_cmd,
"undebug bgp as4 segment",
UNDEBUG_STR
- DEBUG_STR
BGP_STR
+ "BGP AS4 actions\n"
"BGP AS4 aspath segment handling\n")
DEFUN (debug_bgp_fsm,
@@ -417,7 +418,6 @@ ALIAS (no_debug_bgp_fsm,
undebug_bgp_fsm_cmd,
"undebug bgp fsm",
UNDEBUG_STR
- DEBUG_STR
BGP_STR
"Finite State Machine\n")
@@ -715,7 +715,6 @@ ALIAS (no_debug_bgp_zebra,
undebug_bgp_zebra_cmd,
"undebug bgp zebra",
UNDEBUG_STR
- DEBUG_STR
BGP_STR
"BGP Zebra messages\n")
diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c
index 8087a403..edb725a9 100644
--- a/bgpd/bgp_dump.c
+++ b/bgpd/bgp_dump.c
@@ -356,7 +356,11 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
stream_putw(obuf, info->peer->table_dump_index);
/* Originated */
+#ifdef HAVE_CLOCK_MONOTONIC
+ stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime));
+#else
stream_putl (obuf, info->uptime);
+#endif /* HAVE_CLOCK_MONOTONIC */
/* Dump attribute. */
/* Skip prefix & AFI/SAFI for MP_NLRI */
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 9d14683c..1a460c6b 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -243,7 +243,15 @@ bgp_exit (int status)
if (retain_mode)
if_add_hook (IF_DELETE_HOOK, NULL);
for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
- if_delete (ifp);
+ {
+ struct listnode *c_node, *c_nnode;
+ struct connected *c;
+
+ for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
+ bgp_connected_delete (c);
+
+ if_delete (ifp);
+ }
list_free (iflist);
/* reverse bgp_attr_init */
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 9e3427d2..570cc3b7 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "command.h"
#include "privs.h"
#include "linklist.h"
+#include "network.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_fsm.h"
@@ -150,6 +151,7 @@ bgp_accept (struct thread *thread)
zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
return -1;
}
+ set_nonblocking (bgp_sock);
if (BGP_DEBUG (events, EVENTS))
zlog_debug ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
@@ -172,8 +174,11 @@ bgp_accept (struct thread *thread)
}
/* In case of peer is EBGP, we should set TTL for this connection. */
- if (peer_sort (peer1) == BGP_PEER_EBGP)
+ if (peer_sort (peer1) == BGP_PEER_EBGP) {
sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
+ if (peer1->gtsm_hops)
+ sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops);
+ }
/* Make dummy peer until read Open packet. */
if (BGP_DEBUG (events, EVENTS))
@@ -313,8 +318,11 @@ bgp_connect (struct peer *peer)
return -1;
/* If we can get socket for the peer, adjest TTL and make connection. */
- if (peer_sort (peer) == BGP_PEER_EBGP)
+ if (peer_sort (peer) == BGP_PEER_EBGP) {
sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (peer->gtsm_hops)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - peer->gtsm_hops);
+ }
sockopt_reuseaddr (peer->fd);
sockopt_reuseport (peer->fd);
@@ -461,7 +469,10 @@ bgp_socket (unsigned short port, const char *address)
zlog_err ("socket: %s", safe_strerror (errno));
continue;
}
-
+
+ /* if we intend to implement ttl-security, this socket needs ttl=255 */
+ sockopt_ttl (ainfo->ai_family, sock, MAXTTL);
+
ret = bgp_listener (sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret == 0)
++count;
@@ -494,6 +505,9 @@ bgp_socket (unsigned short port, const char *address)
return sock;
}
+ /* if we intend to implement ttl-security, this socket needs ttl=255 */
+ sockopt_ttl (AF_INET, sock, MAXTTL);
+
memset (&sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons (port);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 0cde665e..719cb966 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -276,6 +276,8 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed,
if (bnc->metric != oldbnc->metric)
bnc->metricchanged = 1;
+
+ bgp_unlock_node (oldrn);
}
}
}
@@ -365,6 +367,8 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri,
if (bnc->metric != oldbnc->metric)
bnc->metricchanged = 1;
+
+ bgp_unlock_node (oldrn);
}
}
}
@@ -571,7 +575,7 @@ bgp_connected_add (struct connected *ifc)
}
else
{
- bc = XCALLOC (0, sizeof (struct bgp_connected_ref));
+ bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
bc->refcnt = 1;
rn->info = bc;
}
@@ -596,7 +600,7 @@ bgp_connected_add (struct connected *ifc)
}
else
{
- bc = XCALLOC (0, sizeof (struct bgp_connected_ref));
+ bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
bc->refcnt = 1;
rn->info = bc;
}
@@ -636,7 +640,7 @@ bgp_connected_delete (struct connected *ifc)
bc->refcnt--;
if (bc->refcnt == 0)
{
- XFREE (0, bc);
+ XFREE (MTYPE_BGP_CONN, bc);
rn->info = NULL;
}
bgp_unlock_node (rn);
@@ -662,7 +666,7 @@ bgp_connected_delete (struct connected *ifc)
bc->refcnt--;
if (bc->refcnt == 0)
{
- XFREE (0, bc);
+ XFREE (MTYPE_BGP_CONN, bc);
rn->info = NULL;
}
bgp_unlock_node (rn);
@@ -1136,11 +1140,15 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer)
rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p1);
if (! rn1)
return 0;
+ bgp_unlock_node (rn1);
rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p2);
if (! rn2)
return 0;
+ bgp_unlock_node (rn2);
+ /* This is safe, even with above unlocks, since we are just
+ comparing pointers to the objects, not the objects themselves. */
if (rn1 == rn2)
return 1;
@@ -1316,6 +1324,9 @@ bgp_scan_init (void)
void
bgp_scan_finish (void)
{
+ /* Only the current one needs to be reset. */
+ bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP]);
+
bgp_table_unlock (cache1_table[AFI_IP]);
cache1_table[AFI_IP] = NULL;
@@ -1326,6 +1337,9 @@ bgp_scan_finish (void)
bgp_connected_table[AFI_IP] = NULL;
#ifdef HAVE_IPV6
+ /* Only the current one needs to be reset. */
+ bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP6]);
+
bgp_table_unlock (cache1_table[AFI_IP6]);
cache1_table[AFI_IP6] = NULL;
diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
index 59265dc9..2b1382d8 100644
--- a/bgpd/bgp_open.h
+++ b/bgpd/bgp_open.h
@@ -31,9 +31,9 @@ struct capability_header
/* Generic MP capability data */
struct capability_mp_data
{
- u_int16_t afi;
+ afi_t afi;
u_char reserved;
- u_char safi;
+ safi_t safi;
};
#pragma pack(1)
@@ -55,8 +55,8 @@ struct capability_as4
struct graceful_restart_af
{
- u_int16_t afi;
- u_char safi;
+ afi_t afi;
+ safi_t safi;
u_char flag;
};
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index b29bc1f0..ed2cb73e 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -177,10 +177,11 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
if (rn->prn)
prd = (struct prefix_rd *) &rn->prn->p;
- if (binfo && binfo->extra)
+ if (binfo)
{
- tag = binfo->extra->tag;
from = binfo->peer;
+ if (binfo->extra)
+ tag = binfo->extra->tag;
}
bgp_packet_set_marker (s, BGP_MSG_UPDATE);
@@ -597,7 +598,6 @@ bgp_write (struct thread *thread)
struct stream *s;
int num;
unsigned int count = 0;
- int write_errno;
/* Yes first of all get peer pointer. */
peer = THREAD_ARG (thread);
@@ -610,46 +610,37 @@ bgp_write (struct thread *thread)
return 0;
}
- /* Nonblocking write until TCP output buffer is full. */
- while (1)
+ s = bgp_write_packet (peer);
+ if (!s)
+ return 0; /* nothing to send */
+
+ sockopt_cork (peer->fd, 1);
+
+ /* Nonblocking write until TCP output buffer is full. */
+ do
{
int writenum;
- int val;
-
- s = bgp_write_packet (peer);
- if (! s)
- return 0;
-
- /* XXX: FIXME, the socket should be NONBLOCK from the start
- * status shouldnt need to be toggled on each write
- */
- val = fcntl (peer->fd, F_GETFL, 0);
- fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
/* Number of bytes to be sent. */
writenum = stream_get_endp (s) - stream_get_getp (s);
/* Call write() system call. */
num = write (peer->fd, STREAM_PNT (s), writenum);
- write_errno = errno;
- fcntl (peer->fd, F_SETFL, val);
- if (num <= 0)
+ if (num < 0)
{
- /* Partial write. */
- if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
- break;
+ /* write failed either retry needed or error */
+ if (ERRNO_IO_RETRY(errno))
+ break;
- BGP_EVENT_ADD (peer, TCP_fatal_error);
+ BGP_EVENT_ADD (peer, TCP_fatal_error);
return 0;
}
+
if (num != writenum)
{
+ /* Partial write */
stream_forward_getp (s, num);
-
- if (write_errno == EAGAIN)
- break;
-
- continue;
+ break;
}
/* Retrieve BGP packet type. */
@@ -690,13 +681,14 @@ bgp_write (struct thread *thread)
/* OK we send packet so delete it. */
bgp_packet_delete (peer);
-
- if (++count >= BGP_WRITE_PACKET_MAX)
- break;
}
+ while (++count < BGP_WRITE_PACKET_MAX &&
+ (s = bgp_write_packet (peer)) != NULL);
if (bgp_write_proceed (peer))
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
+ else
+ sockopt_cork (peer->fd, 0);
return 0;
}
@@ -705,7 +697,7 @@ bgp_write (struct thread *thread)
static int
bgp_write_notify (struct peer *peer)
{
- int ret;
+ int ret, val;
u_char type;
struct stream *s;
@@ -715,7 +707,10 @@ bgp_write_notify (struct peer *peer)
return 0;
assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
- /* I'm not sure fd is writable. */
+ /* Put socket in blocking mode. */
+ val = fcntl (peer->fd, F_GETFL, 0);
+ fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
+
ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
if (ret <= 0)
{
@@ -1884,12 +1879,6 @@ bgp_notify_receive (struct peer *peer, bgp_size_t size)
bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
- /* Also apply to Unsupported Capability until remote router support
- capability. */
- if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
- bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
- UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
-
BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
}
@@ -2016,8 +2005,14 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
while (p_pnt < p_end)
{
+ /* If the ORF entry is malformed, want to read as much of it
+ * as possible without going beyond the bounds of the entry,
+ * to maximise debug information.
+ */
+ int ok;
memset (&orfp, 0, sizeof (struct orf_prefix));
common = *p_pnt++;
+ /* after ++: p_pnt <= p_end */
if (common & ORF_COMMON_PART_REMOVE_ALL)
{
if (BGP_DEBUG (normal, NORMAL))
@@ -2025,34 +2020,60 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
prefix_bgp_orf_remove_all (name);
break;
}
- memcpy (&seq, p_pnt, sizeof (u_int32_t));
- p_pnt += sizeof (u_int32_t);
- orfp.seq = ntohl (seq);
- orfp.ge = *p_pnt++;
- orfp.le = *p_pnt++;
- orfp.p.prefixlen = *p_pnt++;
- orfp.p.family = afi2family (afi);
- psize = PSIZE (orfp.p.prefixlen);
- memcpy (&orfp.p.u.prefix, p_pnt, psize);
+ ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
+ if (!ok)
+ {
+ memcpy (&seq, p_pnt, sizeof (u_int32_t));
+ p_pnt += sizeof (u_int32_t);
+ orfp.seq = ntohl (seq);
+ }
+ else
+ p_pnt = p_end ;
+
+ if ((ok = (p_pnt < p_end)))
+ orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
+ if ((ok = (p_pnt < p_end)))
+ orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
+ if ((ok = (p_pnt < p_end)))
+ orfp.p.prefixlen = *p_pnt++ ;
+ orfp.p.family = afi2family (afi); /* afi checked already */
+
+ psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
+ if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
+ {
+ ok = 0 ;
+ psize = prefix_blen(&orfp.p) ;
+ }
+ if (psize > (p_end - p_pnt)) /* valid for packet ? */
+ {
+ ok = 0 ;
+ psize = p_end - p_pnt ;
+ }
+
+ if (psize > 0)
+ memcpy (&orfp.p.u.prefix, p_pnt, psize);
p_pnt += psize;
if (BGP_DEBUG (normal, NORMAL))
- zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
+ zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
peer->host,
(common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
(common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
orfp.seq,
inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
- orfp.p.prefixlen, orfp.ge, orfp.le);
-
- ret = prefix_bgp_orf_set (name, afi, &orfp,
- (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
- (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
-
- if (ret != CMD_SUCCESS)
+ orfp.p.prefixlen, orfp.ge, orfp.le,
+ ok ? "" : " MALFORMED");
+
+ if (ok)
+ ret = prefix_bgp_orf_set (name, afi, &orfp,
+ (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
+ (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
+
+ if (!ok || (ret != CMD_SUCCESS))
{
if (BGP_DEBUG (normal, NORMAL))
- zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
+ zlog_debug ("%s Received misformatted prefixlist ORF."
+ " Remove All pfxlist", peer->host);
prefix_bgp_orf_remove_all (name);
break;
}
@@ -2237,12 +2258,13 @@ bgp_read_packet (struct peer *peer)
return 0;
/* Read packet from fd. */
- nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
+ nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
/* If read byte is smaller than zero then error occured. */
if (nbytes < 0)
{
- if (errno == EAGAIN)
+ /* Transient error should retry */
+ if (nbytes == -2)
return -1;
plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a92ca4e2..5c516f02 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -910,19 +910,6 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
}
}
- /* AS-Pathlimit check */
- if (ri->attr->pathlimit.ttl && peer_sort (peer) == BGP_PEER_EBGP)
- /* Our ASN has not yet been pre-pended, that's done in packet_attribute
- * on output. Hence the test here is for >=.
- */
- if (aspath_count_hops (ri->attr->aspath) >= ri->attr->pathlimit.ttl)
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog_info ("%s [Update:SEND] suppressed, AS-Pathlimit TTL %u exceeded",
- peer->host, ri->attr->pathlimit.ttl);
- return 0;
- }
-
/* For modify attribute, copy it to temporary structure. */
bgp_attr_dup (attr, ri->attr);
@@ -1027,39 +1014,6 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
}
#endif /* HAVE_IPV6 */
- /* AS-Pathlimit: Check ASN for private/confed */
- if (attr->pathlimit.ttl)
- {
- /* locally originated update */
- if (!attr->pathlimit.as)
- attr->pathlimit.as = peer->local_as;
-
- /* if the AS_PATHLIMIT attribute is attached to a prefix by a
- member of a confederation, then when the prefix is advertised outside
- of the confederation boundary, then the AS number of the
- confederation member inside of the AS_PATHLIMIT attribute should be
- replaced by the confederation's AS number. */
- if (peer_sort (from) == BGP_PEER_CONFED
- && peer_sort (peer) != BGP_PEER_CONFED)
- attr->pathlimit.as = peer->local_as;
-
- /* Private ASN should be updated whenever announcement leaves
- * private space. This is deliberately done after simple confed
- * based update..
- */
- if (attr->pathlimit.as >= BGP_PRIVATE_AS_MIN
- && attr->pathlimit.as <= BGP_PRIVATE_AS_MAX)
- {
- if (peer->local_as < BGP_PRIVATE_AS_MIN
- || peer->local_as > BGP_PRIVATE_AS_MAX)
- attr->pathlimit.as = peer->local_as;
- /* Ours is private, try using theirs.. */
- else if (peer->as < BGP_PRIVATE_AS_MIN
- || peer->local_as > BGP_PRIVATE_AS_MAX)
- attr->pathlimit.as = peer->as;
- }
- }
-
/* If this is EBGP peer and remove-private-AS is set. */
if (peer_sort (peer) == BGP_PEER_EBGP
&& peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
@@ -1614,14 +1568,13 @@ bgp_process_queue_init (void)
}
bm->process_main_queue->spec.workfunc = &bgp_process_main;
- bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
- bm->process_rsclient_queue->spec.del_item_data
- = bm->process_main_queue->spec.del_item_data;
- bm->process_main_queue->spec.max_retries
- = bm->process_main_queue->spec.max_retries = 0;
- bm->process_rsclient_queue->spec.hold
- = bm->process_main_queue->spec.hold = 50;
+ bm->process_main_queue->spec.max_retries = 0;
+ bm->process_main_queue->spec.hold = 50;
+
+ memcpy (bm->process_rsclient_queue, bm->process_main_queue,
+ sizeof (struct work_queue *));
+ bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
}
void
@@ -3239,14 +3192,6 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
attr.med = bgp_static->igpmetric;
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- if (bgp_static->ttl)
- {
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
- attr.pathlimit.as = 0;
- attr.pathlimit.ttl = bgp_static->ttl;
- }
-
if (bgp_static->atomic)
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
@@ -3281,7 +3226,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
else
attr_new = bgp_attr_intern (&attr);
- new_attr = *attr_new;
+ bgp_attr_dup(&new_attr, attr_new);
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
@@ -3310,6 +3255,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
bgp_attr_unintern (attr_new);
attr_new = bgp_attr_intern (&new_attr);
+ bgp_attr_extra_free (&new_attr);
for (ri = rn->info; ri; ri = ri->next)
if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
@@ -3395,14 +3341,6 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
attr.med = bgp_static->igpmetric;
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- if (bgp_static->ttl)
- {
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
- attr.pathlimit.as = 0;
- attr.pathlimit.ttl = bgp_static->ttl;
- }
-
if (bgp_static->atomic)
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
@@ -3518,8 +3456,8 @@ bgp_static_update (struct bgp *bgp, struct prefix *p,
}
static void
-bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
- u_char safi, struct prefix_rd *prd, u_char *tag)
+bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi, struct prefix_rd *prd, u_char *tag)
{
struct bgp_node *rn;
struct bgp_info *new;
@@ -3599,8 +3537,8 @@ bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
}
static void
-bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
- u_char safi, struct prefix_rd *prd, u_char *tag)
+bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi, struct prefix_rd *prd, u_char *tag)
{
struct bgp_node *rn;
struct bgp_info *ri;
@@ -3626,44 +3564,17 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
bgp_unlock_node (rn);
}
-static void
-bgp_pathlimit_update_parents (struct bgp *bgp, struct bgp_node *rn,
- int ttl_edge)
-{
- struct bgp_node *parent = rn;
- struct bgp_static *sp;
-
- /* Existing static changed TTL, search parents and adjust their atomic */
- while ((parent = parent->parent))
- if ((sp = parent->info))
- {
- int sp_level = (sp->atomic ? 1 : 0);
- ttl_edge ? sp->atomic++ : sp->atomic--;
-
- /* did we change state of parent whether atomic is set or not? */
- if (sp_level != (sp->atomic ? 1 : 0))
- {
- bgp_static_update (bgp, &parent->p, sp,
- rn->table->afi, rn->table->safi);
- }
- }
-}
-
/* Configure static BGP network. When user don't run zebra, static
route should be installed as valid. */
static int
bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
- u_int16_t afi, u_char safi, const char *rmap, int backdoor,
- u_char ttl)
+ afi_t afi, safi_t safi, const char *rmap, int backdoor)
{
int ret;
struct prefix p;
struct bgp_static *bgp_static;
struct bgp_node *rn;
u_char need_update = 0;
- u_char ttl_change = 0;
- u_char ttl_edge = (ttl ? 1 : 0);
- u_char new = 0;
/* Convert IP prefix string to struct prefix. */
ret = str2prefix (ip_str, &p);
@@ -3692,21 +3603,10 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
bgp_static = rn->info;
/* Check previous routes are installed into BGP. */
- if (bgp_static->valid)
- {
- if (bgp_static->backdoor != backdoor
- || bgp_static->ttl != ttl)
- need_update = 1;
- }
+ if (bgp_static->valid && bgp_static->backdoor != backdoor)
+ need_update = 1;
- /* need to catch TTL set/unset transitions for handling of
- * ATOMIC_AGGREGATE
- */
- if ((bgp_static->ttl ? 1 : 0) != ttl_edge)
- ttl_change = 1;
-
bgp_static->backdoor = backdoor;
- bgp_static->ttl = ttl;
if (rmap)
{
@@ -3733,9 +3633,6 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
bgp_static->valid = 0;
bgp_static->igpmetric = 0;
bgp_static->igpnexthop.s_addr = 0;
- bgp_static->ttl = ttl;
- ttl_change = ttl_edge;
- new = 1;
if (rmap)
{
@@ -3747,39 +3644,6 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
rn->info = bgp_static;
}
- /* ".. sites that choose to advertise the
- * AS_PATHLIMIT path attribute SHOULD advertise the ATOMIC_AGGREGATE on
- * all less specific covering prefixes as well as the more specific
- * prefixes."
- *
- * So:
- * Prefix that has just had pathlimit set/unset:
- * - Must bump ATOMIC refcount on all parents.
- *
- * To catch less specific prefixes:
- * - Must search children for ones with TTL, bump atomic refcount
- * (we dont care if we're deleting a less specific prefix..)
- */
- if (ttl_change)
- {
- /* Existing static changed TTL, search parents and adjust their atomic */
- bgp_pathlimit_update_parents (bgp, rn, ttl_edge);
- }
-
- if (new)
- {
- struct bgp_node *child;
- struct bgp_static *sc;
-
- /* New static, search children and bump this statics atomic.. */
- child = bgp_lock_node (rn); /* route_next_until unlocks it.. */
- while ((child = bgp_route_next_until (child, rn)))
- {
- if ((sc = child->info) && sc->ttl)
- bgp_static->atomic++;
- }
- }
-
/* If BGP scan is not enabled, we should install this route here. */
if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
{
@@ -3798,7 +3662,7 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
/* Configure static BGP network. */
static int
bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
- u_int16_t afi, u_char safi)
+ afi_t afi, safi_t safi)
{
int ret;
struct prefix p;
@@ -3833,9 +3697,6 @@ bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
bgp_static = rn->info;
- /* decrement atomic in parents, see bgp_static_set */
- bgp_pathlimit_update_parents (bgp, rn, 0);
-
/* Update BGP RIB. */
if (! bgp_static->backdoor)
bgp_static_withdraw (bgp, &p, afi, safi);
@@ -4032,23 +3893,10 @@ DEFUN (bgp_network,
"Specify a network to announce via BGP\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-
return bgp_static_set (vty, vty->index, argv[0],
- AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
+ AFI_IP, bgp_node_safi (vty), NULL, 0);
}
-ALIAS (bgp_network,
- bgp_network_ttl_cmd,
- "network A.B.C.D/M pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (bgp_network_route_map,
bgp_network_route_map_cmd,
"network A.B.C.D/M route-map WORD",
@@ -4058,7 +3906,7 @@ DEFUN (bgp_network_route_map,
"Name of the route map\n")
{
return bgp_static_set (vty, vty->index, argv[0],
- AFI_IP, bgp_node_safi (vty), argv[1], 0, 0);
+ AFI_IP, bgp_node_safi (vty), argv[1], 0);
}
DEFUN (bgp_network_backdoor,
@@ -4068,24 +3916,10 @@ DEFUN (bgp_network_backdoor,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Specify a BGP backdoor route\n")
{
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-
return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST,
- NULL, 1, ttl);
+ NULL, 1);
}
-ALIAS (bgp_network_backdoor,
- bgp_network_backdoor_ttl_cmd,
- "network A.B.C.D/M backdoor pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (bgp_network_mask,
bgp_network_mask_cmd,
"network A.B.C.D mask A.B.C.D",
@@ -4096,10 +3930,6 @@ DEFUN (bgp_network_mask,
{
int ret;
char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 3)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255);
ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
if (! ret)
@@ -4109,19 +3939,9 @@ DEFUN (bgp_network_mask,
}
return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
+ AFI_IP, bgp_node_safi (vty), NULL, 0);
}
-ALIAS (bgp_network_mask,
- bgp_network_mask_ttl_cmd,
- "network A.B.C.D mask A.B.C.D pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (bgp_network_mask_route_map,
bgp_network_mask_route_map_cmd,
"network A.B.C.D mask A.B.C.D route-map WORD",
@@ -4143,7 +3963,7 @@ DEFUN (bgp_network_mask_route_map,
}
return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[2], 0, 0);
+ AFI_IP, bgp_node_safi (vty), argv[2], 0);
}
DEFUN (bgp_network_mask_backdoor,
@@ -4157,11 +3977,7 @@ DEFUN (bgp_network_mask_backdoor,
{
int ret;
char prefix_str[BUFSIZ];
- u_char ttl = 0;
- if (argc == 3)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255);
-
ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
if (! ret)
{
@@ -4170,20 +3986,9 @@ DEFUN (bgp_network_mask_backdoor,
}
return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1, ttl);
+ NULL, 1);
}
-ALIAS (bgp_network_mask_backdoor,
- bgp_network_mask_backdoor_ttl_cmd,
- "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (bgp_network_mask_natural,
bgp_network_mask_natural_cmd,
"network A.B.C.D",
@@ -4192,10 +3997,6 @@ DEFUN (bgp_network_mask_natural,
{
int ret;
char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
if (! ret)
@@ -4205,17 +4006,9 @@ DEFUN (bgp_network_mask_natural,
}
return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
+ AFI_IP, bgp_node_safi (vty), NULL, 0);
}
-ALIAS (bgp_network_mask_natural,
- bgp_network_mask_natural_ttl_cmd,
- "network A.B.C.D pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (bgp_network_mask_natural_route_map,
bgp_network_mask_natural_route_map_cmd,
"network A.B.C.D route-map WORD",
@@ -4235,7 +4028,7 @@ DEFUN (bgp_network_mask_natural_route_map,
}
return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[1], 0, 0);
+ AFI_IP, bgp_node_safi (vty), argv[1], 0);
}
DEFUN (bgp_network_mask_natural_backdoor,
@@ -4247,10 +4040,6 @@ DEFUN (bgp_network_mask_natural_backdoor,
{
int ret;
char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
if (! ret)
@@ -4260,18 +4049,9 @@ DEFUN (bgp_network_mask_natural_backdoor,
}
return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1, ttl);
+ NULL, 1);
}
-ALIAS (bgp_network_mask_natural_backdoor,
- bgp_network_mask_natural_backdoor_ttl_cmd,
- "network A.B.C.D backdoor pathlimit (1-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (no_bgp_network,
no_bgp_network_cmd,
"no network A.B.C.D/M",
@@ -4284,15 +4064,6 @@ DEFUN (no_bgp_network,
}
ALIAS (no_bgp_network,
- no_bgp_network_ttl_cmd,
- "no network A.B.C.D/M pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
-ALIAS (no_bgp_network,
no_bgp_network_route_map_cmd,
"no network A.B.C.D/M route-map WORD",
NO_STR
@@ -4309,16 +4080,6 @@ ALIAS (no_bgp_network,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Specify a BGP backdoor route\n")
-ALIAS (no_bgp_network,
- no_bgp_network_backdoor_ttl_cmd,
- "no network A.B.C.D/M backdoor pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (no_bgp_network_mask,
no_bgp_network_mask_cmd,
"no network A.B.C.D mask A.B.C.D",
@@ -4342,17 +4103,6 @@ DEFUN (no_bgp_network_mask,
bgp_node_safi (vty));
}
-ALIAS (no_bgp_network,
- no_bgp_network_mask_ttl_cmd,
- "no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
ALIAS (no_bgp_network_mask,
no_bgp_network_mask_route_map_cmd,
"no network A.B.C.D mask A.B.C.D route-map WORD",
@@ -4374,18 +4124,6 @@ ALIAS (no_bgp_network_mask,
"Network mask\n"
"Specify a BGP backdoor route\n")
-ALIAS (no_bgp_network_mask,
- no_bgp_network_mask_backdoor_ttl_cmd,
- "no network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (no_bgp_network_mask_natural,
no_bgp_network_mask_natural_cmd,
"no network A.B.C.D",
@@ -4424,25 +4162,6 @@ ALIAS (no_bgp_network_mask_natural,
"Network number\n"
"Specify a BGP backdoor route\n")
-ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_ttl_cmd,
- "no network A.B.C.D pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
-ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_backdoor_ttl_cmd,
- "no network A.B.C.D backdoor pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
#ifdef HAVE_IPV6
DEFUN (ipv6_bgp_network,
ipv6_bgp_network_cmd,
@@ -4450,23 +4169,10 @@ DEFUN (ipv6_bgp_network,
"Specify a network to announce via BGP\n"
"IPv6 prefix <network>/<length>\n")
{
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-
return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST,
- NULL, 0, ttl);
+ NULL, 0);
}
-ALIAS (ipv6_bgp_network,
- ipv6_bgp_network_ttl_cmd,
- "network X:X::X:X/M pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
DEFUN (ipv6_bgp_network_route_map,
ipv6_bgp_network_route_map_cmd,
"network X:X::X:X/M route-map WORD",
@@ -4476,7 +4182,7 @@ DEFUN (ipv6_bgp_network_route_map,
"Name of the route map\n")
{
return bgp_static_set (vty, vty->index, argv[0], AFI_IP6,
- bgp_node_safi (vty), argv[1], 0, 0);
+ bgp_node_safi (vty), argv[1], 0);
}
DEFUN (no_ipv6_bgp_network,
@@ -4498,15 +4204,6 @@ ALIAS (no_ipv6_bgp_network,
"Route-map to modify the attributes\n"
"Name of the route map\n")
-ALIAS (no_ipv6_bgp_network,
- no_ipv6_bgp_network_ttl_cmd,
- "no network X:X::X:X/M pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
ALIAS (ipv6_bgp_network,
old_ipv6_bgp_network_cmd,
"ipv6 bgp network X:X::X:X/M",
@@ -4524,6 +4221,129 @@ ALIAS (no_ipv6_bgp_network,
"Specify a network to announce via BGP\n"
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
#endif /* HAVE_IPV6 */
+
+/* stubs for removed AS-Pathlimit commands, kept for config compatibility */
+ALIAS_DEPRECATED (bgp_network,
+ bgp_network_ttl_cmd,
+ "network A.B.C.D/M pathlimit <0-255>",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_backdoor,
+ bgp_network_backdoor_ttl_cmd,
+ "network A.B.C.D/M backdoor pathlimit <0-255>",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Specify a BGP backdoor route\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask,
+ bgp_network_mask_ttl_cmd,
+ "network A.B.C.D mask A.B.C.D pathlimit <0-255>",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask_backdoor,
+ bgp_network_mask_backdoor_ttl_cmd,
+ "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Specify a BGP backdoor route\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask_natural,
+ bgp_network_mask_natural_ttl_cmd,
+ "network A.B.C.D pathlimit <0-255>",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask_natural_backdoor,
+ bgp_network_mask_natural_backdoor_ttl_cmd,
+ "network A.B.C.D backdoor pathlimit (1-255>",
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Specify a BGP backdoor route\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network,
+ no_bgp_network_ttl_cmd,
+ "no network A.B.C.D/M pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network,
+ no_bgp_network_backdoor_ttl_cmd,
+ "no network A.B.C.D/M backdoor pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Specify a BGP backdoor route\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network,
+ no_bgp_network_mask_ttl_cmd,
+ "no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network_mask,
+ no_bgp_network_mask_backdoor_ttl_cmd,
+ "no network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Network mask\n"
+ "Network mask\n"
+ "Specify a BGP backdoor route\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network_mask_natural,
+ no_bgp_network_mask_natural_ttl_cmd,
+ "no network A.B.C.D pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network_mask_natural,
+ no_bgp_network_mask_natural_backdoor_ttl_cmd,
+ "no network A.B.C.D backdoor pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "Network number\n"
+ "Specify a BGP backdoor route\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+#ifdef HAVE_IPV6
+ALIAS_DEPRECATED (ipv6_bgp_network,
+ ipv6_bgp_network_ttl_cmd,
+ "network X:X::X:X/M pathlimit <0-255>",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_ttl_cmd,
+ "no network X:X::X:X/M pathlimit <0-255>",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "AS-Path hopcount limit attribute\n"
+ "AS-Pathlimit TTL, in number of AS-Path hops\n")
+#endif /* HAVE_IPV6 */
/* Aggreagete address:
@@ -4986,9 +4806,8 @@ bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
#define AGGREGATE_AS_SET 1
static int
-bgp_aggregate_set (struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi,
- u_char summary_only, u_char as_set)
+bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
+ afi_t afi, safi_t safi)
{
int ret;
struct prefix p;
@@ -5009,34 +4828,33 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
bgp = vty->index;
/* Old configuration check. */
- rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
-
- if (rn->info)
+ rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
+ if (! rn)
{
- vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
- bgp_unlock_node (rn);
+ vty_out (vty, "%% There is no aggregate-address configuration.%s",
+ VTY_NEWLINE);
return CMD_WARNING;
}
- /* Make aggregate address structure. */
- aggregate = bgp_aggregate_new ();
- aggregate->summary_only = summary_only;
- aggregate->as_set = as_set;
- aggregate->safi = safi;
- rn->info = aggregate;
+ aggregate = rn->info;
+ if (aggregate->safi & SAFI_UNICAST)
+ bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
+ if (aggregate->safi & SAFI_MULTICAST)
+ bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
- /* Aggregate address insert into BGP routing table. */
- if (safi & SAFI_UNICAST)
- bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (safi & SAFI_MULTICAST)
- bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+ /* Unlock aggregate address configuration. */
+ rn->info = NULL;
+ bgp_aggregate_free (aggregate);
+ bgp_unlock_node (rn);
+ bgp_unlock_node (rn);
return CMD_SUCCESS;
}
static int
-bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi)
+bgp_aggregate_set (struct vty *vty, const char *prefix_str,
+ afi_t afi, safi_t safi,
+ u_char summary_only, u_char as_set)
{
int ret;
struct prefix p;
@@ -5057,25 +4875,33 @@ bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
bgp = vty->index;
/* Old configuration check. */
- rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
- if (! rn)
+ rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
+
+ if (rn->info)
{
- vty_out (vty, "%% There is no aggregate-address configuration.%s",
- VTY_NEWLINE);
- return CMD_WARNING;
+ vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
+ /* try to remove the old entry */
+ ret = bgp_aggregate_unset (vty, prefix_str, afi, safi);
+ if (ret)
+ {
+ vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
+ bgp_unlock_node (rn);
+ return CMD_WARNING;
+ }
}
- aggregate = rn->info;
- if (aggregate->safi & SAFI_UNICAST)
- bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (aggregate->safi & SAFI_MULTICAST)
- bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+ /* Make aggregate address structure. */
+ aggregate = bgp_aggregate_new ();
+ aggregate->summary_only = summary_only;
+ aggregate->as_set = as_set;
+ aggregate->safi = safi;
+ rn->info = aggregate;
- /* Unlock aggregate address configuration. */
- rn->info = NULL;
- bgp_aggregate_free (aggregate);
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
+ /* Aggregate address insert into BGP routing table. */
+ if (safi & SAFI_UNICAST)
+ bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
+ if (safi & SAFI_MULTICAST)
+ bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
return CMD_SUCCESS;
}
@@ -5723,12 +5549,12 @@ route_vty_out (struct vty *vty, struct prefix *p,
#endif /* HAVE_IPV6 */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, "%10d", attr->med);
+ vty_out (vty, "%10u", attr->med);
else
vty_out (vty, " ");
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- vty_out (vty, "%7d", attr->local_pref);
+ vty_out (vty, "%7u", attr->local_pref);
else
vty_out (vty, " ");
@@ -5788,16 +5614,16 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p,
#endif /* HAVE_IPV6 */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, "%10d", attr->med);
+ vty_out (vty, "%10u", attr->med);
else
vty_out (vty, " ");
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- vty_out (vty, "%7d", attr->local_pref);
+ vty_out (vty, "%7u", attr->local_pref);
else
vty_out (vty, " ");
- vty_out (vty, "%7d ", (attr->extra ? attr->extra->weight : 0));
+ vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
/* Print aspath */
if (attr->aspath)
@@ -5979,6 +5805,9 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
char buf1[BUFSIZ];
struct attr *attr;
int sockunion_vty_out (struct vty *, union sockunion *);
+#ifdef HAVE_CLOCK_MONOTONIC
+ time_t tbuf;
+#endif
attr = binfo->attr;
@@ -6064,15 +5893,15 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, ", metric %d", attr->med);
+ vty_out (vty, ", metric %u", attr->med);
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
- vty_out (vty, ", localpref %d", attr->local_pref);
+ vty_out (vty, ", localpref %u", attr->local_pref);
else
- vty_out (vty, ", localpref %d", bgp->default_local_pref);
+ vty_out (vty, ", localpref %u", bgp->default_local_pref);
if (attr->extra && attr->extra->weight != 0)
- vty_out (vty, ", weight %d", attr->extra->weight);
+ vty_out (vty, ", weight %u", attr->extra->weight);
if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
vty_out (vty, ", valid");
@@ -6130,22 +5959,16 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
vty_out (vty, "%s", VTY_NEWLINE);
}
- /* 7: AS Pathlimit */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AS_PATHLIMIT))
- {
-
- vty_out (vty, " AS-Pathlimit: %u",
- attr->pathlimit.ttl);
- if (attr->pathlimit.as)
- vty_out (vty, " (%u)", attr->pathlimit.as);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
if (binfo->extra && binfo->extra->damp_info)
bgp_damp_info_vty (vty, binfo);
/* Line 7 display Uptime */
- vty_out (vty, " Last update: %s", ctime (&binfo->uptime));
+#ifdef HAVE_CLOCK_MONOTONIC
+ tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
+ vty_out (vty, " Last update: %s", ctime(&tbuf));
+#else
+ vty_out (vty, " Last update: %s", ctime(&binfo->uptime));
+#endif /* HAVE_CLOCK_MONOTONIC */
}
vty_out (vty, "%s", VTY_NEWLINE);
}
@@ -6554,7 +6377,10 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
if ((rm = bgp_node_match (table, &match)) != NULL)
{
if (prefix_check && rm->p.prefixlen != match.prefixlen)
- continue;
+ {
+ bgp_unlock_node (rm);
+ continue;
+ }
for (ri = rm->info; ri; ri = ri->next)
{
@@ -6568,6 +6394,8 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
display++;
route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
}
+
+ bgp_unlock_node (rm);
}
}
}
@@ -6591,6 +6419,8 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi);
}
}
+
+ bgp_unlock_node (rn);
}
}
@@ -6663,6 +6493,15 @@ DEFUN (show_ip_bgp_ipv4,
return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
}
+ALIAS (show_ip_bgp_ipv4,
+ show_bgp_ipv4_safi_cmd,
+ "show bgp ipv4 (unicast|multicast)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n")
+
DEFUN (show_ip_bgp_route,
show_ip_bgp_route_cmd,
"show ip bgp A.B.C.D",
@@ -6691,6 +6530,16 @@ DEFUN (show_ip_bgp_ipv4_route,
return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
}
+ALIAS (show_ip_bgp_ipv4_route,
+ show_bgp_ipv4_safi_route_cmd,
+ "show bgp ipv4 (unicast|multicast) A.B.C.D",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Network in the BGP routing table to display\n")
+
DEFUN (show_ip_bgp_vpnv4_all_route,
show_ip_bgp_vpnv4_all_route_cmd,
"show ip bgp vpnv4 all A.B.C.D",
@@ -6755,6 +6604,16 @@ DEFUN (show_ip_bgp_ipv4_prefix,
return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
}
+ALIAS (show_ip_bgp_ipv4_prefix,
+ show_bgp_ipv4_safi_prefix_cmd,
+ "show bgp ipv4 (unicast|multicast) A.B.C.D/M",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
DEFUN (show_ip_bgp_vpnv4_all_prefix,
show_ip_bgp_vpnv4_all_prefix_cmd,
"show ip bgp vpnv4 all A.B.C.D/M",
@@ -6857,6 +6716,22 @@ ALIAS (show_bgp,
BGP_STR
"Address family\n")
+DEFUN (show_bgp_ipv6_safi,
+ show_bgp_ipv6_safi_cmd,
+ "show bgp ipv6 (unicast|multicast)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
+ NULL);
+
+ return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL);
+}
+
/* old command */
DEFUN (show_ipv6_bgp,
show_ipv6_bgp_cmd,
@@ -6887,6 +6762,22 @@ ALIAS (show_bgp_route,
"Address family\n"
"Network in the BGP routing table to display\n")
+DEFUN (show_bgp_ipv6_safi_route,
+ show_bgp_ipv6_safi_route_cmd,
+ "show bgp ipv6 (unicast|multicast) X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Network in the BGP routing table to display\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0);
+
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0);
+}
+
/* old command */
DEFUN (show_ipv6_bgp_route,
show_ipv6_bgp_route_cmd,
@@ -6917,6 +6808,22 @@ ALIAS (show_bgp_prefix,
"Address family\n"
"IPv6 prefix <network>/<length>\n")
+DEFUN (show_bgp_ipv6_safi_prefix,
+ show_bgp_ipv6_safi_prefix_cmd,
+ "show bgp ipv6 (unicast|multicast) X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1);
+
+ return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1);
+}
+
/* old command */
DEFUN (show_ipv6_bgp_prefix,
show_ipv6_bgp_prefix_cmd,
@@ -7621,15 +7528,36 @@ DEFUN (show_ipv6_mbgp_community_all,
#endif /* HAVE_IPV6 */
static int
-bgp_show_community (struct vty *vty, int argc, const char **argv, int exact,
- u_int16_t afi, u_char safi)
+bgp_show_community (struct vty *vty, const char *view_name, int argc,
+ const char **argv, int exact, afi_t afi, safi_t safi)
{
struct community *com;
struct buffer *b;
+ struct bgp *bgp;
int i;
char *str;
int first = 0;
+ /* BGP structure lookup */
+ if (view_name)
+ {
+ bgp = bgp_lookup_by_name (view_name);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
b = buffer_new (1024);
for (i = 0; i < argc; i++)
{
@@ -7657,7 +7585,7 @@ bgp_show_community (struct vty *vty, int argc, const char **argv, int exact,
return CMD_WARNING;
}
- return bgp_show (vty, NULL, afi, safi,
+ return bgp_show (vty, bgp, afi, safi,
(exact ? bgp_show_type_community_exact :
bgp_show_type_community), com);
}
@@ -7674,7 +7602,7 @@ DEFUN (show_ip_bgp_community,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
{
- return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
}
ALIAS (show_ip_bgp_community,
@@ -7753,9 +7681,9 @@ DEFUN (show_ip_bgp_ipv4_community,
"Do not export to next AS (well-known community)\n")
{
if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
- return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
}
ALIAS (show_ip_bgp_ipv4_community,
@@ -7827,6 +7755,177 @@ ALIAS (show_ip_bgp_ipv4_community,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
+DEFUN (show_bgp_view_afi_safi_community_all,
+ show_bgp_view_afi_safi_community_all_cmd,
+#ifdef HAVE_IPV6
+ "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community",
+#else
+ "show bgp view WORD ipv4 (unicast|multicast) community",
+#endif
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+#ifdef HAVE_IPV6
+ "Address family\n"
+#endif
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes containing communities\n")
+{
+ int afi;
+ int safi;
+ struct bgp *bgp;
+
+ /* BGP structure lookup. */
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+#ifdef HAVE_IPV6
+ afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+ safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+#else
+ afi = AFI_IP;
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+#endif
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL);
+}
+
+DEFUN (show_bgp_view_afi_safi_community,
+ show_bgp_view_afi_safi_community_cmd,
+#ifdef HAVE_IPV6
+ "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
+#else
+ "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+#ifdef HAVE_IPV6
+ "Address family\n"
+#endif
+ "Address family modifier\n"
+ "Address family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+{
+ int afi;
+ int safi;
+
+#ifdef HAVE_IPV6
+ afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+ safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ return bgp_show_community (vty, argv[0], argc-3, &argv[3], 0, afi, safi);
+#else
+ afi = AFI_IP;
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ return bgp_show_community (vty, argv[0], argc-2, &argv[2], 0, afi, safi);
+#endif
+}
+
+ALIAS (show_bgp_view_afi_safi_community,
+ show_bgp_view_afi_safi_community2_cmd,
+#ifdef HAVE_IPV6
+ "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#else
+ "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+#ifdef HAVE_IPV6
+ "Address family\n"
+#endif
+ "Address family modifier\n"
+ "Address family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_view_afi_safi_community,
+ show_bgp_view_afi_safi_community3_cmd,
+#ifdef HAVE_IPV6
+ "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#else
+ "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+#ifdef HAVE_IPV6
+ "Address family\n"
+#endif
+ "Address family modifier\n"
+ "Address family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_view_afi_safi_community,
+ show_bgp_view_afi_safi_community4_cmd,
+#ifdef HAVE_IPV6
+ "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#else
+ "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+#ifdef HAVE_IPV6
+ "Address family\n"
+#endif
+ "Address family modifier\n"
+ "Address family modifier\n"
+ "Display routes matching the communities\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "community number\n"
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n")
+
DEFUN (show_ip_bgp_community_exact,
show_ip_bgp_community_exact_cmd,
"show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
@@ -7840,7 +7939,7 @@ DEFUN (show_ip_bgp_community_exact,
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
{
- return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
}
ALIAS (show_ip_bgp_community_exact,
@@ -7923,9 +8022,9 @@ DEFUN (show_ip_bgp_ipv4_community_exact,
"Exact match of the communities")
{
if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
- return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
}
ALIAS (show_ip_bgp_ipv4_community_exact,
@@ -8012,7 +8111,7 @@ DEFUN (show_bgp_community,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
{
- return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
}
ALIAS (show_bgp_community,
@@ -8157,7 +8256,7 @@ DEFUN (show_ipv6_bgp_community,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
{
- return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
}
/* old command */
@@ -8235,7 +8334,7 @@ DEFUN (show_bgp_community_exact,
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
{
- return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
}
ALIAS (show_bgp_community_exact,
@@ -8388,7 +8487,7 @@ DEFUN (show_ipv6_bgp_community_exact,
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
{
- return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
}
/* old command */
@@ -8470,7 +8569,7 @@ DEFUN (show_ipv6_mbgp_community,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
{
- return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
}
/* old command */
@@ -8550,7 +8649,7 @@ DEFUN (show_ipv6_mbgp_community_exact,
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
{
- return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
}
/* old command */
@@ -8622,7 +8721,7 @@ ALIAS (show_ipv6_mbgp_community_exact,
static int
bgp_show_community_list (struct vty *vty, const char *com, int exact,
- u_int16_t afi, u_char safi)
+ afi_t afi, safi_t safi)
{
struct community_list *list;
@@ -9959,6 +10058,56 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1);
}
+DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes,
+ show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd,
+#ifdef HAVE_IPV6
+ "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)",
+#else
+ "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)",
+#endif
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+#ifdef HAVE_IPV6
+ "Address family\n"
+#endif
+ "Address family modifier\n"
+ "Address family modifier\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Display the advertised routes to neighbor\n"
+ "Display the received routes from neighbor\n")
+{
+ int afi;
+ int safi;
+ int in;
+ struct peer *peer;
+
+#ifdef HAVE_IPV6
+ peer = peer_lookup_in_view (vty, argv[0], argv[3]);
+#else
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+#endif
+
+ if (! peer)
+ return CMD_WARNING;
+
+#ifdef HAVE_IPV6
+ afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+ safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ in = (strncmp (argv[4], "r", 1) == 0) ? 1 : 0;
+#else
+ afi = AFI_IP;
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ in = (strncmp (argv[3], "r", 1) == 0) ? 1 : 0;
+#endif
+
+ return peer_adj_routes (vty, peer, afi, safi, in);
+}
+
DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
show_ip_bgp_neighbor_received_prefix_filter_cmd,
"show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
@@ -10366,6 +10515,65 @@ ALIAS (show_ip_bgp_view_rsclient,
"Information about Route Server Client\n"
NEIGHBOR_ADDR_STR)
+DEFUN (show_bgp_view_ipv4_safi_rsclient,
+ show_bgp_view_ipv4_safi_rsclient_cmd,
+ "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+{
+ struct bgp_table *table;
+ struct peer *peer;
+ safi_t safi;
+
+ if (argc == 3) {
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ } else {
+ peer = peer_lookup_in_view (vty, NULL, argv[1]);
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ }
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP][safi])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ table = peer->rib[AFI_IP][safi];
+
+ return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL);
+}
+
+ALIAS (show_bgp_view_ipv4_safi_rsclient,
+ show_bgp_ipv4_safi_rsclient_cmd,
+ "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+
DEFUN (show_ip_bgp_view_rsclient_route,
show_ip_bgp_view_rsclient_route_cmd,
"show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
@@ -10439,6 +10647,87 @@ ALIAS (show_ip_bgp_view_rsclient_route,
NEIGHBOR_ADDR_STR
"Network in the BGP routing table to display\n")
+DEFUN (show_bgp_view_ipv4_safi_rsclient_route,
+ show_bgp_view_ipv4_safi_rsclient_route_cmd,
+ "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+ safi_t safi;
+
+ /* BGP structure lookup. */
+ if (argc == 4)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (argc == 4) {
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ } else {
+ peer = peer_lookup_in_view (vty, NULL, argv[1]);
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ }
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP][safi])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][safi],
+ (argc == 4) ? argv[3] : argv[2],
+ AFI_IP, safi, NULL, 0);
+}
+
+ALIAS (show_bgp_view_ipv4_safi_rsclient_route,
+ show_bgp_ipv4_safi_rsclient_route_cmd,
+ "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+
DEFUN (show_ip_bgp_view_rsclient_prefix,
show_ip_bgp_view_rsclient_prefix_cmd,
"show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
@@ -10512,6 +10801,86 @@ ALIAS (show_ip_bgp_view_rsclient_prefix,
NEIGHBOR_ADDR_STR
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix,
+ show_bgp_view_ipv4_safi_rsclient_prefix_cmd,
+ "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+ safi_t safi;
+
+ /* BGP structure lookup. */
+ if (argc == 4)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (argc == 4) {
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ } else {
+ peer = peer_lookup_in_view (vty, NULL, argv[1]);
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ }
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP][safi])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
+ PEER_FLAG_RSERVER_CLIENT))
+{
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][safi],
+ (argc == 4) ? argv[3] : argv[2],
+ AFI_IP, safi, NULL, 1);
+}
+
+ALIAS (show_bgp_view_ipv4_safi_rsclient_prefix,
+ show_bgp_ipv4_safi_rsclient_prefix_cmd,
+ "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
#ifdef HAVE_IPV6
DEFUN (show_bgp_view_neighbor_routes,
@@ -10778,6 +11147,65 @@ ALIAS (show_bgp_view_rsclient,
"Information about Route Server Client\n"
NEIGHBOR_ADDR_STR)
+DEFUN (show_bgp_view_ipv6_safi_rsclient,
+ show_bgp_view_ipv6_safi_rsclient_cmd,
+ "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+{
+ struct bgp_table *table;
+ struct peer *peer;
+ safi_t safi;
+
+ if (argc == 3) {
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ } else {
+ peer = peer_lookup_in_view (vty, NULL, argv[1]);
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ }
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP6][safi])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ table = peer->rib[AFI_IP6][safi];
+
+ return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL);
+}
+
+ALIAS (show_bgp_view_ipv6_safi_rsclient,
+ show_bgp_ipv6_safi_rsclient_cmd,
+ "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR)
+
DEFUN (show_bgp_view_rsclient_route,
show_bgp_view_rsclient_route_cmd,
"show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
@@ -10849,6 +11277,87 @@ ALIAS (show_bgp_view_rsclient_route,
NEIGHBOR_ADDR_STR
"Network in the BGP routing table to display\n")
+DEFUN (show_bgp_view_ipv6_safi_rsclient_route,
+ show_bgp_view_ipv6_safi_rsclient_route_cmd,
+ "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+ safi_t safi;
+
+ /* BGP structure lookup. */
+ if (argc == 4)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (argc == 4) {
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ } else {
+ peer = peer_lookup_in_view (vty, NULL, argv[1]);
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ }
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP6][safi])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi],
+ PEER_FLAG_RSERVER_CLIENT))
+ {
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][safi],
+ (argc == 4) ? argv[3] : argv[2],
+ AFI_IP6, safi, NULL, 0);
+}
+
+ALIAS (show_bgp_view_ipv6_safi_rsclient_route,
+ show_bgp_ipv6_safi_rsclient_route_cmd,
+ "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "Network in the BGP routing table to display\n")
+
DEFUN (show_bgp_view_rsclient_prefix,
show_bgp_view_rsclient_prefix_cmd,
"show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
@@ -10920,6 +11429,87 @@ ALIAS (show_bgp_view_rsclient_prefix,
NEIGHBOR_ADDR_STR
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix,
+ show_bgp_view_ipv6_safi_rsclient_prefix_cmd,
+ "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "BGP view name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IP prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+ struct bgp *bgp;
+ struct peer *peer;
+ safi_t safi;
+
+ /* BGP structure lookup. */
+ if (argc == 4)
+ {
+ bgp = bgp_lookup_by_name (argv[0]);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (argc == 4) {
+ peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ } else {
+ peer = peer_lookup_in_view (vty, NULL, argv[1]);
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ }
+
+ if (! peer)
+ return CMD_WARNING;
+
+ if (! peer->afc[AFI_IP6][safi])
+ {
+ vty_out (vty, "%% Activate the neighbor for the address family first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+ if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi],
+ PEER_FLAG_RSERVER_CLIENT))
+{
+ vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][safi],
+ (argc == 4) ? argv[3] : argv[2],
+ AFI_IP6, safi, NULL, 1);
+}
+
+ALIAS (show_bgp_view_ipv6_safi_rsclient_prefix,
+ show_bgp_ipv6_safi_rsclient_prefix_cmd,
+ "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Client\n"
+ NEIGHBOR_ADDR_STR
+ "IP prefix <network>/<length>, e.g., 3ffe::/16\n")
+
#endif /* HAVE_IPV6 */
struct bgp_table *bgp_distance_table;
@@ -11348,41 +11938,49 @@ bgp_clear_damp_route (struct vty *vty, const char *view_name,
if ((table = rn->info) != NULL)
if ((rm = bgp_node_match (table, &match)) != NULL)
- if (! prefix_check || rm->p.prefixlen == match.prefixlen)
- {
- ri = rm->info;
- while (ri)
- {
- if (ri->extra && ri->extra->damp_info)
- {
- ri_temp = ri->next;
- bgp_damp_info_free (ri->extra->damp_info, 1);
- ri = ri_temp;
- }
- else
- ri = ri->next;
- }
- }
+ {
+ if (! prefix_check || rm->p.prefixlen == match.prefixlen)
+ {
+ ri = rm->info;
+ while (ri)
+ {
+ if (ri->extra && ri->extra->damp_info)
+ {
+ ri_temp = ri->next;
+ bgp_damp_info_free (ri->extra->damp_info, 1);
+ ri = ri_temp;
+ }
+ else
+ ri = ri->next;
+ }
+ }
+
+ bgp_unlock_node (rm);
+ }
}
}
else
{
if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
- if (! prefix_check || rn->p.prefixlen == match.prefixlen)
- {
- ri = rn->info;
- while (ri)
- {
- if (ri->extra && ri->extra->damp_info)
- {
- ri_temp = ri->next;
- bgp_damp_info_free (ri->extra->damp_info, 1);
- ri = ri_temp;
- }
- else
- ri = ri->next;
- }
- }
+ {
+ if (! prefix_check || rn->p.prefixlen == match.prefixlen)
+ {
+ ri = rn->info;
+ while (ri)
+ {
+ if (ri->extra && ri->extra->damp_info)
+ {
+ ri_temp = ri->next;
+ bgp_damp_info_free (ri->extra->damp_info, 1);
+ ri = ri_temp;
+ }
+ else
+ ri = ri->next;
+ }
+ }
+
+ bgp_unlock_node (rn);
+ }
}
return CMD_SUCCESS;
@@ -11547,8 +12145,6 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
{
if (bgp_static->backdoor)
vty_out (vty, " backdoor");
- if (bgp_static->ttl)
- vty_out (vty, " pathlimit %u", bgp_static->ttl);
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -11637,12 +12233,6 @@ bgp_route_init (void)
install_element (BGP_NODE, &bgp_network_backdoor_cmd);
install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd);
install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
- install_element (BGP_NODE, &bgp_network_ttl_cmd);
- install_element (BGP_NODE, &bgp_network_mask_ttl_cmd);
- install_element (BGP_NODE, &bgp_network_mask_natural_ttl_cmd);
- install_element (BGP_NODE, &bgp_network_backdoor_ttl_cmd);
- install_element (BGP_NODE, &bgp_network_mask_backdoor_ttl_cmd);
- install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
install_element (BGP_NODE, &no_bgp_network_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
@@ -11652,12 +12242,6 @@ bgp_route_init (void)
install_element (BGP_NODE, &no_bgp_network_backdoor_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_backdoor_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_cmd);
- install_element (BGP_NODE, &no_bgp_network_ttl_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_ttl_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_natural_ttl_cmd);
- install_element (BGP_NODE, &no_bgp_network_backdoor_ttl_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
install_element (BGP_NODE, &aggregate_address_cmd);
install_element (BGP_NODE, &aggregate_address_mask_cmd);
@@ -11687,23 +12271,13 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_ttl_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_ttl_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_ttl_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_backdoor_ttl_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_backdoor_ttl_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_ttl_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_ttl_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_ttl_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_backdoor_ttl_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
+
install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
install_element (BGP_IPV4_NODE, &aggregate_address_summary_only_cmd);
@@ -11732,24 +12306,12 @@ bgp_route_init (void)
install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_backdoor_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_backdoor_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_route_map_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_backdoor_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_summary_only_cmd);
@@ -11773,12 +12335,15 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ip_bgp_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_cmd);
install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_cmd);
@@ -11804,6 +12369,11 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_afi_safi_community_all_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_afi_safi_community_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_afi_safi_community2_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_afi_safi_community3_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_afi_safi_community4_cmd);
install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd);
install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd);
install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd);
@@ -11822,6 +12392,7 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
@@ -11839,20 +12410,28 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_ip_bgp_rsclient_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_cmd);
install_element (VIEW_NODE, &show_ip_bgp_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_neighbor_advertised_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_neighbor_received_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
/* Restricted node: VIEW_NODE - (set of dangerous commands) */
install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_route_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_route_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_prefix_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_prefix_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_view_route_cmd);
@@ -11865,6 +12444,11 @@ bgp_route_init (void)
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community_all_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community2_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community3_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community4_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_community_exact_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_community2_exact_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_community3_exact_cmd);
@@ -11874,18 +12458,25 @@ bgp_route_init (void)
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_route_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_prefix_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_prefix_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_view_cmd);
@@ -11911,6 +12502,11 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community_all_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community2_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community3_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community4_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_community_exact_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_community2_exact_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_community3_exact_cmd);
@@ -11929,6 +12525,7 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
@@ -11946,13 +12543,19 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_flap_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_view_neighbor_advertised_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_view_neighbor_received_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
/* BGP dampening clear commands */
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
@@ -11970,10 +12573,8 @@ bgp_route_init (void)
/* New config IPv6 BGP commands. */
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
- install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_route_map_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd);
install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_summary_only_cmd);
@@ -11991,10 +12592,13 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_bgp_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_cmd);
install_element (VIEW_NODE, &show_bgp_route_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_route_cmd);
install_element (VIEW_NODE, &show_bgp_prefix_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_prefix_cmd);
install_element (VIEW_NODE, &show_bgp_regexp_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_regexp_cmd);
install_element (VIEW_NODE, &show_bgp_prefix_list_cmd);
@@ -12040,8 +12644,11 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_bgp_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_rsclient_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_cmd);
install_element (VIEW_NODE, &show_bgp_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd);
install_element (VIEW_NODE, &show_bgp_rsclient_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd);
install_element (VIEW_NODE, &show_bgp_view_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_cmd);
install_element (VIEW_NODE, &show_bgp_view_route_cmd);
@@ -12061,16 +12668,21 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_bgp_view_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_view_rsclient_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_cmd);
install_element (VIEW_NODE, &show_bgp_view_rsclient_route_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
install_element (VIEW_NODE, &show_bgp_view_rsclient_prefix_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
/* Restricted:
* VIEW_NODE - (set of dangerous commands) - (commands dependent on prev)
*/
install_element (RESTRICTED_NODE, &show_bgp_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_prefix_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_prefix_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_prefix_cmd);
install_element (RESTRICTED_NODE, &show_bgp_community_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_cmd);
install_element (RESTRICTED_NODE, &show_bgp_community2_cmd);
@@ -12088,7 +12700,9 @@ bgp_route_init (void)
install_element (RESTRICTED_NODE, &show_bgp_community4_exact_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_exact_cmd);
install_element (RESTRICTED_NODE, &show_bgp_rsclient_route_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_rsclient_prefix_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd);
install_element (RESTRICTED_NODE, &show_bgp_view_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_view_prefix_cmd);
@@ -12096,14 +12710,19 @@ bgp_route_init (void)
install_element (RESTRICTED_NODE, &show_bgp_view_neighbor_received_prefix_filter_cmd);
install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd);
install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_route_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_prefix_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_cmd);
install_element (ENABLE_NODE, &show_bgp_route_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_route_cmd);
install_element (ENABLE_NODE, &show_bgp_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_regexp_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_regexp_cmd);
install_element (ENABLE_NODE, &show_bgp_prefix_list_cmd);
@@ -12149,8 +12768,11 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_bgp_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_bgp_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_cmd);
install_element (ENABLE_NODE, &show_bgp_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd);
install_element (ENABLE_NODE, &show_bgp_rsclient_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_view_cmd);
install_element (ENABLE_NODE, &show_bgp_view_ipv6_cmd);
install_element (ENABLE_NODE, &show_bgp_view_route_cmd);
@@ -12170,8 +12792,11 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_bgp_view_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
install_element (ENABLE_NODE, &show_bgp_view_rsclient_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_cmd);
install_element (ENABLE_NODE, &show_bgp_view_rsclient_route_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
install_element (ENABLE_NODE, &show_bgp_view_rsclient_prefix_cmd);
+ install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
/* Statistics */
install_element (ENABLE_NODE, &show_bgp_statistics_cmd);
@@ -12292,6 +12917,54 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &bgp_damp_set3_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
+
+ /* Deprecated AS-Pathlimit commands */
+ install_element (BGP_NODE, &bgp_network_ttl_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_ttl_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_natural_ttl_cmd);
+ install_element (BGP_NODE, &bgp_network_backdoor_ttl_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_backdoor_ttl_cmd);
+ install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
+
+ install_element (BGP_NODE, &no_bgp_network_ttl_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_ttl_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_natural_ttl_cmd);
+ install_element (BGP_NODE, &no_bgp_network_backdoor_ttl_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
+ install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
+
+ install_element (BGP_IPV4_NODE, &bgp_network_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_backdoor_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_backdoor_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
+
+ install_element (BGP_IPV4_NODE, &no_bgp_network_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_backdoor_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
+
+ install_element (BGP_IPV4M_NODE, &bgp_network_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_backdoor_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_backdoor_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
+
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_backdoor_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
+
+#ifdef HAVE_IPV6
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd);
+#endif
}
void
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 5eed3486..3e528596 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -116,9 +116,6 @@ struct bgp_static
/* MPLS label. */
u_char tag[3];
-
- /* AS-Pathlimit TTL */
- u_char ttl;
};
/* Flags which indicate a route is unuseable in some form */
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index aa7dbce1..255b25ae 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -92,107 +92,15 @@ o Cisco route-map
origin : Done
tag : (This will not be implemented by bgpd)
weight : Done
- pathlimit : Done
o Local extention
set ipv6 next-hop global: Done
set ipv6 next-hop local : Done
- set pathlimit ttl : Done
set as-path exclude : Done
- match pathlimit as : Done
*/
-/* Compiles either AS or TTL argument. It is amused the VTY code
- * has already range-checked the values to be suitable as TTL or ASN
- */
-static void *
-route_pathlimit_compile (const char *arg)
-{
- unsigned long tmp;
- u_int32_t *val;
- char *endptr = NULL;
-
- /* TTL or AS value shoud be integer. */
- if (! all_digit (arg))
- return NULL;
-
- tmp = strtoul (arg, &endptr, 10);
- if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
- return NULL;
-
- if (!(val = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t))))
- return NULL;
-
- *val = tmp;
-
- return val;
-}
-
-static void
-route_pathlimit_free (void *rule)
-{
- XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
-}
-
-static route_map_result_t
-route_match_pathlimit_as (void *rule, struct prefix *prefix, route_map_object_t type,
- void *object)
-{
- struct bgp_info *info = object;
- struct attr *attr = info->attr;
- uint32_t as = *(uint32_t *)rule;
-
- if (type != RMAP_BGP)
- return RMAP_NOMATCH;
-
- if (!attr->pathlimit.as)
- return RMAP_NOMATCH;
-
- if (as == attr->pathlimit.as)
- return RMAP_MATCH;
-
- return RMAP_NOMATCH;
-}
-
-/* 'match pathlimit as' */
-struct route_map_rule_cmd route_match_pathlimit_as_cmd =
-{
- "pathlimit as",
- route_match_pathlimit_as,
- route_pathlimit_compile,
- route_pathlimit_free
-};
-
-/* Set pathlimit TTL. */
-static route_map_result_t
-route_set_pathlimit_ttl (void *rule, struct prefix *prefix,
- route_map_object_t type, void *object)
-{
- struct bgp_info *info = object;
- struct attr *attr = info->attr;
- u_char ttl = *(uint32_t *)rule;
-
- if (type == RMAP_BGP)
- {
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
- attr->pathlimit.ttl = ttl;
- attr->pathlimit.as = 0;
- }
-
- return RMAP_OKAY;
-}
-
-/* Set local preference rule structure. */
-struct route_map_rule_cmd route_set_pathlimit_ttl_cmd =
-{
- "pathlimit ttl",
- route_set_pathlimit_ttl,
- route_pathlimit_compile,
- route_pathlimit_free,
-};
-
/* 'match peer (A.B.C.D|X:X::X:X)' */
/* Compares the peer specified in the 'match peer' clause with the peer
@@ -1485,6 +1393,13 @@ route_set_community_delete (void *rule, struct prefix *prefix,
new = community_uniq_sort (merge);
community_free (merge);
+ /* HACK: if the old community is not intern'd,
+ * we should free it here, or all reference to it may be lost.
+ * Really need to cleanup attribute caching sometime.
+ */
+ if (old->refcnt == 0)
+ community_free (old);
+
if (new->size == 0)
{
binfo->attr->community = NULL;
@@ -3743,17 +3658,17 @@ ALIAS (no_set_originator_id,
"BGP originator ID attribute\n"
"IP address of originator\n")
-DEFUN (set_pathlimit_ttl,
+DEFUN_DEPRECATED (set_pathlimit_ttl,
set_pathlimit_ttl_cmd,
"set pathlimit ttl <1-255>",
SET_STR
"BGP AS-Pathlimit attribute\n"
"Set AS-Path Hop-count TTL\n")
{
- return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
+ return CMD_SUCCESS;
}
-DEFUN (no_set_pathlimit_ttl,
+DEFUN_DEPRECATED (no_set_pathlimit_ttl,
no_set_pathlimit_ttl_cmd,
"no set pathlimit ttl",
NO_STR
@@ -3761,10 +3676,7 @@ DEFUN (no_set_pathlimit_ttl,
"BGP AS-Pathlimit attribute\n"
"Set AS-Path Hop-count TTL\n")
{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
+ return CMD_SUCCESS;
}
ALIAS (no_set_pathlimit_ttl,
@@ -3775,17 +3687,17 @@ ALIAS (no_set_pathlimit_ttl,
"BGP AS-Pathlimit attribute\n"
"Set AS-Path Hop-count TTL\n")
-DEFUN (match_pathlimit_as,
+DEFUN_DEPRECATED (match_pathlimit_as,
match_pathlimit_as_cmd,
"match pathlimit as <1-65535>",
MATCH_STR
"BGP AS-Pathlimit attribute\n"
"Match Pathlimit AS number\n")
{
- return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
+ return CMD_SUCCESS;
}
-DEFUN (no_match_pathlimit_as,
+DEFUN_DEPRECATED (no_match_pathlimit_as,
no_match_pathlimit_as_cmd,
"no match pathlimit as",
NO_STR
@@ -3793,10 +3705,7 @@ DEFUN (no_match_pathlimit_as,
"BGP AS-Pathlimit attribute\n"
"Match Pathlimit AS number\n")
{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
-
- return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
+ return CMD_SUCCESS;
}
ALIAS (no_match_pathlimit_as,
@@ -3959,10 +3868,9 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
#endif /* HAVE_IPV6 */
- /* AS-Pathlimit */
- route_map_install_match (&route_match_pathlimit_as_cmd);
- route_map_install_set (&route_set_pathlimit_ttl_cmd);
-
+ /* AS-Pathlimit: functionality removed, commands kept for
+ * compatibility.
+ */
install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c
index 91cab606..a249c23d 100644
--- a/bgpd/bgp_table.c
+++ b/bgpd/bgp_table.c
@@ -350,7 +350,6 @@ bgp_node_get (struct bgp_table *const table, struct prefix *p)
if (new->p.prefixlen != p->prefixlen)
{
match = new;
- bgp_lock_node (match);
new = bgp_node_set (table, p);
set_link (match, new);
table->count++;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 88be52e2..e7e7dba1 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -213,6 +213,12 @@ bgp_vty_return (struct vty *vty, int ret)
case BGP_ERR_TCPSIG_FAILED:
str = "Error while applying TCP-Sig to session(s)";
break;
+ case BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK:
+ str = "ebgp-multihop and ttl-security cannot be configured together";
+ break;
+ case BGP_ERR_NO_IBGP_WITH_TTLHACK:
+ str = "ttl-security only allowed for EBGP peers";
+ break;
}
if (str)
{
@@ -2636,9 +2642,7 @@ peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
else
VTY_GET_INTEGER_RANGE ("TTL", ttl, ttl_str, 1, 255);
- peer_ebgp_multihop_set (peer, ttl);
-
- return CMD_SUCCESS;
+ return bgp_vty_return (vty, peer_ebgp_multihop_set (peer, ttl));
}
static int
@@ -2650,9 +2654,7 @@ peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
if (! peer)
return CMD_WARNING;
- peer_ebgp_multihop_unset (peer);
-
- return CMD_SUCCESS;
+ return bgp_vty_return (vty, peer_ebgp_multihop_unset (peer));
}
/* neighbor ebgp-multihop. */
@@ -3954,6 +3956,42 @@ DEFUN (no_neighbor_allowas_in,
return bgp_vty_return (vty, ret);
}
+DEFUN (neighbor_ttl_security,
+ neighbor_ttl_security_cmd,
+ NEIGHBOR_CMD2 "ttl-security hops <1-254>",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify the maximum number of hops to the BGP peer\n")
+{
+ struct peer *peer;
+ int gtsm_hops;
+
+ peer = peer_and_group_lookup_vty (vty, argv[0]);
+ if (! peer)
+ return CMD_WARNING;
+
+ VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254);
+
+ return bgp_vty_return (vty, peer_ttl_security_hops_set (peer, gtsm_hops));
+}
+
+DEFUN (no_neighbor_ttl_security,
+ no_neighbor_ttl_security_cmd,
+ NO_NEIGHBOR_CMD2 "ttl-security hops <1-254>",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify the maximum number of hops to the BGP peer\n")
+{
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty (vty, argv[0]);
+ if (! peer)
+ return CMD_WARNING;
+
+ return bgp_vty_return (vty, peer_ttl_security_hops_unset (peer));
+}
+
/* Address family configuration. */
DEFUN (address_family_ipv4,
address_family_ipv4_cmd,
@@ -6864,6 +6902,16 @@ DEFUN (show_ip_bgp_ipv4_summary,
return bgp_show_summary_vty (vty, NULL, AFI_IP, SAFI_UNICAST);
}
+ALIAS (show_ip_bgp_ipv4_summary,
+ show_bgp_ipv4_safi_summary_cmd,
+ "show bgp ipv4 (unicast|multicast) summary",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Summary of BGP neighbor status\n")
+
DEFUN (show_ip_bgp_instance_ipv4_summary,
show_ip_bgp_instance_ipv4_summary_cmd,
"show ip bgp view WORD ipv4 (unicast|multicast) summary",
@@ -6883,6 +6931,18 @@ DEFUN (show_ip_bgp_instance_ipv4_summary,
return bgp_show_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST);
}
+ALIAS (show_ip_bgp_instance_ipv4_summary,
+ show_bgp_instance_ipv4_safi_summary_cmd,
+ "show bgp view WORD ipv4 (unicast|multicast) summary",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Summary of BGP neighbor status\n")
+
DEFUN (show_ip_bgp_vpnv4_all_summary,
show_ip_bgp_vpnv4_all_summary_cmd,
"show ip bgp vpnv4 all summary",
@@ -6961,6 +7021,40 @@ ALIAS (show_bgp_instance_summary,
"Address family\n"
"Summary of BGP neighbor status\n")
+DEFUN (show_bgp_ipv6_safi_summary,
+ show_bgp_ipv6_safi_summary_cmd,
+ "show bgp ipv6 (unicast|multicast) summary",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Summary of BGP neighbor status\n")
+{
+ if (strncmp (argv[0], "m", 1) == 0)
+ return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_MULTICAST);
+
+ return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_UNICAST);
+}
+
+DEFUN (show_bgp_instance_ipv6_safi_summary,
+ show_bgp_instance_ipv6_safi_summary_cmd,
+ "show bgp view WORD ipv6 (unicast|multicast) summary",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Summary of BGP neighbor status\n")
+{
+ if (strncmp (argv[1], "m", 1) == 0)
+ return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_MULTICAST);
+
+ return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST);
+}
+
/* old command */
DEFUN (show_ipv6_bgp_summary,
show_ipv6_bgp_summary_cmd,
@@ -7552,10 +7646,16 @@ bgp_show_peer (struct vty *vty, struct peer *p)
p->host, VTY_NEWLINE);
}
- /* EBGP Multihop */
- if (peer_sort (p) != BGP_PEER_IBGP && p->ttl > 1)
- vty_out (vty, " External BGP neighbor may be up to %d hops away.%s",
- p->ttl, VTY_NEWLINE);
+ /* EBGP Multihop and GTSM */
+ if (peer_sort (p) != BGP_PEER_IBGP)
+ {
+ if (p->gtsm_hops > 0)
+ vty_out (vty, " External BGP neighbor may be up to %d hops away.%s",
+ p->gtsm_hops, VTY_NEWLINE);
+ else if (p->ttl > 1)
+ vty_out (vty, " External BGP neighbor may be up to %d hops away.%s",
+ p->ttl, VTY_NEWLINE);
+ }
/* Local address. */
if (p->su_local)
@@ -8162,6 +8262,41 @@ DEFUN (show_ip_bgp_instance_ipv4_rsclient_summary,
return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST);
}
+DEFUN (show_bgp_instance_ipv4_safi_rsclient_summary,
+ show_bgp_instance_ipv4_safi_rsclient_summary_cmd,
+ "show bgp view WORD ipv4 (unicast|multicast) rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ safi_t safi;
+
+ if (argc == 2) {
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, safi);
+ } else {
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP, safi);
+ }
+}
+
+ALIAS (show_bgp_instance_ipv4_safi_rsclient_summary,
+ show_bgp_ipv4_safi_rsclient_summary_cmd,
+ "show bgp ipv4 (unicast|multicast) rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+
#ifdef HAVE_IPV6
DEFUN (show_bgp_rsclient_summary,
show_bgp_rsclient_summary_cmd,
@@ -8206,6 +8341,42 @@ ALIAS (show_bgp_instance_rsclient_summary,
"Address family\n"
"Information about Route Server Clients\n"
"Summary of all Route Server Clients\n")
+
+DEFUN (show_bgp_instance_ipv6_safi_rsclient_summary,
+ show_bgp_instance_ipv6_safi_rsclient_summary_cmd,
+ "show bgp view WORD ipv6 (unicast|multicast) rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "BGP view\n"
+ "View name\n"
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+{
+ safi_t safi;
+
+ if (argc == 2) {
+ safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP6, safi);
+ } else {
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+ return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP6, safi);
+ }
+}
+
+ALIAS (show_bgp_instance_ipv6_safi_rsclient_summary,
+ show_bgp_ipv6_safi_rsclient_summary_cmd,
+ "show bgp ipv6 (unicast|multicast) rsclient summary",
+ SHOW_STR
+ BGP_STR
+ "Address family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Information about Route Server Clients\n"
+ "Summary of all Route Server Clients\n")
+
#endif /* HAVE IPV6 */
/* Redistribute VTY commands. */
@@ -9752,38 +9923,50 @@ bgp_vty_init (void)
install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
#ifdef HAVE_IPV6
install_element (VIEW_NODE, &show_bgp_summary_cmd);
install_element (VIEW_NODE, &show_bgp_instance_summary_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_summary_cmd);
install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
#endif /* HAVE_IPV6 */
install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_instance_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
#ifdef HAVE_IPV6
install_element (RESTRICTED_NODE, &show_bgp_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
#endif /* HAVE_IPV6 */
install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
#ifdef HAVE_IPV6
install_element (ENABLE_NODE, &show_bgp_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_ipv6_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
#endif /* HAVE_IPV6 */
/* "show ip bgp neighbors" commands. */
@@ -9847,28 +10030,40 @@ bgp_vty_init (void)
install_element (VIEW_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd);
#ifdef HAVE_IPV6
install_element (VIEW_NODE, &show_bgp_rsclient_summary_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
install_element (VIEW_NODE, &show_bgp_instance_rsclient_summary_cmd);
install_element (VIEW_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd);
+ install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_rsclient_summary_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd);
+ install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_rsclient_summary_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd);
+ install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd);
#endif /* HAVE_IPV6 */
/* "show ip bgp paths" commands. */
@@ -9909,6 +10104,10 @@ bgp_vty_init (void)
install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_metric_rmap_cmd);
#endif /* HAVE_IPV6 */
+ /* ttl_security commands */
+ install_element (BGP_NODE, &neighbor_ttl_security_cmd);
+ install_element (BGP_NODE, &no_neighbor_ttl_security_cmd);
+
/* "show bgp memory" commands. */
install_element (VIEW_NODE, &show_bgp_memory_cmd);
install_element (RESTRICTED_NODE, &show_bgp_memory_cmd);
@@ -9952,7 +10151,7 @@ community_list_perror (struct vty *vty, int ret)
switch (ret)
{
case COMMUNITY_LIST_ERR_CANT_FIND_LIST:
- vty_out (vty, "%% Can't find communit-list%s", VTY_NEWLINE);
+ vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE);
break;
case COMMUNITY_LIST_ERR_MALFORMED_VAL:
vty_out (vty, "%% Malformed community-list value%s", VTY_NEWLINE);
@@ -10313,7 +10512,7 @@ DEFUN (show_ip_community_list_arg,
list = community_list_lookup (bgp_clist, argv[0], COMMUNITY_LIST_MASTER);
if (! list)
{
- vty_out (vty, "%% Can't find communit-list%s", VTY_NEWLINE);
+ vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -10663,7 +10862,7 @@ DEFUN (show_ip_extcommunity_list_arg,
list = community_list_lookup (bgp_clist, argv[0], EXTCOMMUNITY_LIST_MASTER);
if (! list)
{
- vty_out (vty, "%% Can't find extcommunit-list%s", VTY_NEWLINE);
+ vty_out (vty, "%% Can't find extcommunity-list%s", VTY_NEWLINE);
return CMD_WARNING;
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 882fe37c..ee0cc5da 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1379,6 +1379,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_hops = 0;
group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
@@ -1416,6 +1417,9 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
/* TTL */
peer->ttl = conf->ttl;
+ /* GTSM hops */
+ peer->gtsm_hops = conf->gtsm_hops;
+
/* Weight */
peer->weight = conf->weight;
@@ -2663,10 +2667,36 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl)
{
struct peer_group *group;
struct listnode *node, *nnode;
+ struct peer *peer1;
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
+ /* see comment in peer_ttl_security_hops_set() */
+ if (ttl != MAXTTL)
+ {
+ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ group = peer->group;
+ if (group->conf->gtsm_hops != 0)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
+ {
+ if (peer_sort (peer1) == BGP_PEER_IBGP)
+ continue;
+
+ if (peer1->gtsm_hops != 0)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+ }
+ }
+ else
+ {
+ if (peer->gtsm_hops != 0)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+ }
+ }
+
peer->ttl = ttl;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
@@ -2700,6 +2730,9 @@ peer_ebgp_multihop_unset (struct peer *peer)
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
+ if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+
if (peer_group_active (peer))
peer->ttl = peer->group->conf->ttl;
else
@@ -4331,6 +4364,137 @@ peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
return 0;
}
+/* Set # of hops between us and BGP peer. */
+int
+peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
+{
+ struct peer_group *group;
+ struct listnode *node, *nnode;
+ struct peer *peer1;
+ int ret;
+
+ zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
+
+ if (peer_sort (peer) == BGP_PEER_IBGP)
+ return BGP_ERR_NO_IBGP_WITH_TTLHACK;
+
+ /* We cannot configure ttl-security hops when ebgp-multihop is already
+ set. For non peer-groups, the check is simple. For peer-groups, it's
+ slightly messy, because we need to check both the peer-group structure
+ and all peer-group members for any trace of ebgp-multihop configuration
+ before actually applying the ttl-security rules. Cisco really made a
+ mess of this configuration parameter, and OpenBGPD got it right.
+ */
+
+ if (peer->gtsm_hops == 0) {
+ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ group = peer->group;
+ if (group->conf->ttl != 1)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
+ {
+ if (peer_sort (peer1) == BGP_PEER_IBGP)
+ continue;
+
+ if (peer1->ttl != 1)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+ }
+ }
+ else
+ {
+ if (peer->ttl != 1)
+ return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+ }
+ /* specify MAXTTL on outgoing packets */
+ ret = peer_ebgp_multihop_set (peer, MAXTTL);
+ if (ret != 0)
+ return ret;
+ }
+
+ peer->gtsm_hops = gtsm_hops;
+
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
+ }
+ else
+ {
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+ {
+ if (peer_sort (peer) == BGP_PEER_IBGP)
+ continue;
+
+ peer->gtsm_hops = group->conf->gtsm_hops;
+
+ /* Change setting of existing peer
+ * established then change value (may break connectivity)
+ * not established yet (teardown session and restart)
+ * no session then do nothing (will get handled by next connection)
+ */
+ if (peer->status == Established)
+ {
+ if (peer->fd >= 0 && peer->gtsm_hops != 0)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd,
+ MAXTTL + 1 - peer->gtsm_hops);
+ }
+ else if (peer->status < Established)
+ {
+ if (BGP_DEBUG (events, EVENTS))
+ zlog_debug ("%s Min-ttl changed", peer->host);
+ BGP_EVENT_ADD (peer, BGP_Stop);
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+peer_ttl_security_hops_unset (struct peer *peer)
+{
+ struct peer_group *group;
+ struct listnode *node, *nnode;
+ struct peer *opeer;
+
+ zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
+
+ if (peer_sort (peer) == BGP_PEER_IBGP)
+ return 0;
+
+ /* if a peer-group member, then reset to peer-group default rather than 0 */
+ if (peer_group_active (peer))
+ peer->gtsm_hops = peer->group->conf->gtsm_hops;
+ else
+ peer->gtsm_hops = 0;
+
+ opeer = peer;
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
+ }
+ else
+ {
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+ {
+ if (peer_sort (peer) == BGP_PEER_IBGP)
+ continue;
+
+ peer->gtsm_hops = 0;
+
+ if (peer->fd >= 0)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
+ }
+ }
+
+ return peer_ebgp_multihop_unset (opeer);
+}
+
int
peer_clear (struct peer *peer)
{
@@ -4635,12 +4799,19 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
/* EBGP multihop. */
- if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
+ if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1 &&
+ !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL))
if (! peer_group_active (peer) ||
g_peer->ttl != peer->ttl)
vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
VTY_NEWLINE);
+ /* ttl-security hops */
+ if (peer_sort (peer) != BGP_PEER_IBGP && peer->gtsm_hops != 0)
+ if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)
+ vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
+ peer->gtsm_hops, VTY_NEWLINE);
+
/* disable-connected-check. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
if (! peer_group_active (peer) ||
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index a5afaedc..4da19e71 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -303,6 +303,7 @@ struct peer
/* Peer information */
int fd; /* File descriptor */
int ttl; /* TTL of TCP connection to the peer. */
+ int gtsm_hops; /* minimum hopcount to peer */
char *desc; /* Description of the peer. */
unsigned short port; /* Destination port for peer */
char *host; /* Printable address of the peer. */
@@ -800,7 +801,9 @@ enum bgp_clear_type
#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -27
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -28
#define BGP_ERR_TCPSIG_FAILED -29
-#define BGP_ERR_MAX -30
+#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -30
+#define BGP_ERR_NO_IBGP_WITH_TTLHACK -31
+#define BGP_ERR_MAX -32
extern struct bgp_master *bm;
@@ -953,4 +956,7 @@ extern int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t);
extern int peer_clear (struct peer *);
extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);
+extern int peer_ttl_security_hops_set (struct peer *, int);
+extern int peer_ttl_security_hops_unset (struct peer *);
+
#endif /* _QUAGGA_BGPD_H */
diff --git a/configure.ac b/configure.ac
index e7c99b0d..b981d5b1 100755
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@
## $Id$
AC_PREREQ(2.53)
-AC_INIT(Quagga, 0.99.16, [http://bugzilla.quagga.net])
+AC_INIT(Quagga, 0.99.18, [https://bugzilla.quagga.net])
AC_CONFIG_SRCDIR(lib/zebra.h)
AC_CONFIG_MACRO_DIR([m4])
@@ -219,15 +219,14 @@ AC_ARG_WITH(libpam,
AC_ARG_ENABLE(tcp-zebra,
[ --enable-tcp-zebra enable TCP/IP socket connection between zebra and protocol daemon])
AC_ARG_ENABLE(opaque-lsa,
-[ --enable-opaque-lsa enable OSPF Opaque-LSA with OSPFAPI support (RFC2370)])
+ AC_HELP_STRING([--disable-opaque-lsa],[do not build OSPF Opaque-LSA with OSPFAPI support (RFC2370)]))
AC_ARG_ENABLE(ospfapi,
-[ --disable-ospfapi do not build OSPFAPI to access the OSPF LSA Database,
- (this is the default if --enable-opaque-lsa is not set)])
+[ --disable-ospfapi do not build OSPFAPI to access the OSPF LSA Database])
AC_ARG_ENABLE(ospfclient,
[ --disable-ospfclient do not build OSPFAPI client for OSPFAPI,
(this is the default if --disable-ospfapi is set)])
AC_ARG_ENABLE(ospf-te,
-[ --enable-ospf-te enable Traffic Engineering Extension to OSPF])
+ AC_HELP_STRING([--disable-ospf-te],[disable Traffic Engineering Extension to OSPF]))
AC_ARG_ENABLE(multipath,
[ --enable-multipath=ARG enable multipath function, ARG must be digit])
AC_ARG_ENABLE(user,
@@ -292,11 +291,11 @@ if test "${enable_tcp_zebra}" = "yes"; then
AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
fi
-if test "${enable_opaque_lsa}" = "yes"; then
+if test "${enable_opaque_lsa}" != "no"; then
AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
fi
-if test "${enable_ospf_te}" = "yes"; then
+if test "${enable_ospf_te}" != "no"; then
AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
AC_DEFINE(HAVE_OSPF_TE,,OSPF TE)
fi
@@ -1201,7 +1200,7 @@ else
fi
OSPFCLIENT=""
-if test "${enable_opaque_lsa}" = "yes"; then
+if test "${enable_opaque_lsa}" != "no"; then
if test "${enable_ospfapi}" != "no";then
AC_DEFINE(SUPPORT_OSPF_API,,OSPFAPI)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index c3016b2b..cd4d71bd 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -43,7 +43,7 @@ info_TEXINFOS = quagga.texi
# us to have a generic automatic .pdf rule to build the figure sources
# because it cant just work from the png's directly it seems - contrary
# to the documentation...
-quagga.pdf: $(info_TEXINFOS) $(figures_pdf)
+quagga.pdf: $(info_TEXINFOS) $(figures_pdf) $(quagga_TEXINFOS)
$(TEXI2PDF) -o "$@" $<
quagga_TEXINFOS = appendix.texi basic.texi bgpd.texi filter.texi install.texi \
diff --git a/doc/bgpd.texi b/doc/bgpd.texi
index 40156b7f..e7463300 100644
--- a/doc/bgpd.texi
+++ b/doc/bgpd.texi
@@ -149,29 +149,6 @@ routes if they aren't present in their IGP routing tables; @code{bgpd}
doesn't care about IGP routes when announcing its routes.
@end deffn
-@deffn {BGP} {network @var{A.B.C.D/M} pathlimit <0-255>} {}
-This command configures a route to be originated into BGP, just as with the
-previous command, but additionally sets an AS-Pathlimit TTL to be advertised
-on the route. See draft-ietf-idr-as-pathlimit.
-
-Specifying a TTL of 0 can be used to remove pathlimit from a previously
-configured network statement.
-
-Note that when advertising prefixes with AS-Pathlimit set, all less-specific
-prefixes advertised SHOULD also have the Atomic-Aggregate attribute set.
-Failure to do so increases the risks of accidental routing loops occuring.
-
-This implementation will try to automatically set Atomic-Aggregate as
-appropriate on any less-specific prefixes originated by the same speaker,
-however it will not (and often can not) do so where @b{other} speakers in
-the AS are originating more specifics.
-
-Hence the system administrator must take care to ensure that all
-less-specific prefixes originated carry atomic-aggregate as appropriate, by
-manually configuring speakers originating less-specifics to set
-Atomic-Aggregate on those advertisements!
-@end deffn
-
@deffn {BGP} {no network @var{A.B.C.D/M}} {}
@end deffn
diff --git a/doc/main.texi b/doc/main.texi
index 9966b356..a5759137 100644
--- a/doc/main.texi
+++ b/doc/main.texi
@@ -49,9 +49,9 @@ Up or down the current interface.
@end deffn
@deffn {Interface Command} {ip address @var{address/prefix}} {}
-@deffnx {Interface Command} {ip6 address @var{address/prefix}} {}
+@deffnx {Interface Command} {ipv6 address @var{address/prefix}} {}
@deffnx {Interface Command} {no ip address @var{address/prefix}} {}
-@deffnx {Interface Command} {no ip6 address @var{address/prefix}} {}
+@deffnx {Interface Command} {no ipv6 address @var{address/prefix}} {}
Set the IPv4 or IPv6 address/prefix for the interface.
@end deffn
diff --git a/doc/routemap.texi b/doc/routemap.texi
index 9ac001c4..db3e72d2 100644
--- a/doc/routemap.texi
+++ b/doc/routemap.texi
@@ -155,10 +155,6 @@ Matches the specified @var{metric}.
Matches the specified @var{community_list}
@end deffn
-@deffn {Route-map Command} {match pathlimit as @var{ASN}} {}
-Matches the specified AS-Pathlimit @var{ASN}.
-@end deffn
-
@node Route Map Set Command
@section Route Map Set Command
@@ -194,16 +190,6 @@ Set the BGP-4+ global IPv6 nexthop address.
Set the BGP-4+ link local IPv6 nexthop address.
@end deffn
-@deffn {Route-map Command} {set pathlimit ttl @var{ttl}} {}
-Sets the specified AS-Pathlimit @var{ttl} on the route. This will also cause
-the AS to be set to the local AS.
-
-Note that the AS-Pathlimit RFC specifies that speakers advertising this
-attribute should set Atomic-aggregate on all less specific routes. Setting
-AS-Pathlimit by route-map does not do this, the user must do so themselves,
-as they wish.
-@end deffn
-
@node Route Map Call Command
@section Route Map Call Command
diff --git a/lib/command.c b/lib/command.c
index 478125f2..264e0f7b 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -3056,7 +3056,7 @@ DEFUN (config_logmsg,
if ((level = level_match(argv[0])) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
- zlog(NULL, level, ((message = argv_concat(argv, argc, 1)) ? message : ""));
+ zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, 1)) ? message : ""));
if (message)
XFREE(MTYPE_TMP, message);
return CMD_SUCCESS;
@@ -3650,6 +3650,8 @@ cmd_init (int terminal)
install_element (VIEW_NODE, &show_thread_cpu_cmd);
install_element (ENABLE_NODE, &show_thread_cpu_cmd);
install_element (RESTRICTED_NODE, &show_thread_cpu_cmd);
+
+ install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
install_element (VIEW_NODE, &show_work_queues_cmd);
install_element (ENABLE_NODE, &show_work_queues_cmd);
}
diff --git a/lib/distribute.c b/lib/distribute.c
index 242a225c..420849da 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -114,16 +114,11 @@ distribute_get (const char *ifname)
}
static unsigned int
-distribute_hash_make (struct distribute *dist)
+distribute_hash_make (void *arg)
{
- unsigned int i, key;
+ const struct distribute *dist = arg;
- key = 0;
- if (dist->ifname)
- for (i = 0; i < strlen (dist->ifname); i++)
- key += dist->ifname[i];
-
- return key;
+ return dist->ifname ? string_hash_make (dist->ifname) : 0;
}
/* If two distribute-list have same value then return 1 else return
@@ -763,7 +758,7 @@ distribute_list_reset ()
void
distribute_list_init (int node)
{
- disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make,
+ disthash = hash_create (distribute_hash_make,
(int (*) (const void *, const void *)) distribute_cmp);
if(node==RIP_NODE) {
diff --git a/lib/hash.c b/lib/hash.c
index 672327ec..6db79ea7 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -101,6 +101,17 @@ hash_lookup (struct hash *hash, void *data)
return hash_get (hash, data, NULL);
}
+/* Simple Bernstein hash which is simple and fast for common case */
+unsigned int string_hash_make (const char *str)
+{
+ unsigned int hash = 0;
+
+ while (*str)
+ hash = (hash * 33) ^ (unsigned int) *str++;
+
+ return hash;
+}
+
/* This function release registered value from specified hash. When
release is successfully finished, return the data pointer in the
hash backet. */
diff --git a/lib/hash.h b/lib/hash.h
index f4b1c23e..4cb772e5 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -70,4 +70,6 @@ extern void hash_iterate (struct hash *,
extern void hash_clean (struct hash *, void (*) (void *));
extern void hash_free (struct hash *);
+extern unsigned int string_hash_make (const char *);
+
#endif /* _ZEBRA_HASH_H */
diff --git a/lib/if.c b/lib/if.c
index e3107116..86f754b6 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -664,7 +664,7 @@ connected_log (struct connected *connected, char *str)
strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
BUFSIZ - strlen(logbuf));
}
- zlog (NULL, LOG_INFO, logbuf);
+ zlog (NULL, LOG_INFO, "%s", logbuf);
}
/* If two connected address has same prefix return 1. */
@@ -878,3 +878,21 @@ if_init (void)
memset (&if_master, 0, sizeof if_master);
}
+
+void
+if_terminate (void)
+{
+ for (;;)
+ {
+ struct interface *ifp;
+
+ ifp = listnode_head (iflist);
+ if (ifp == NULL)
+ break;
+
+ if_delete (ifp);
+ }
+
+ list_delete (iflist);
+ iflist = NULL;
+}
diff --git a/lib/if.h b/lib/if.h
index c99ab81b..841ce51e 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -266,6 +266,7 @@ extern int if_is_pointopoint (struct interface *);
extern int if_is_multicast (struct interface *);
extern void if_add_hook (int, int (*)(struct interface *));
extern void if_init (void);
+extern void if_terminate (void);
extern void if_dump_all (void);
extern const char *if_flag_dump(unsigned long);
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index ddc62fd5..9774be4b 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -109,14 +109,9 @@ if_rmap_get (const char *ifname)
static unsigned int
if_rmap_hash_make (void *data)
{
- struct if_rmap *if_rmap = data;
- unsigned int i, key;
+ const struct if_rmap *if_rmap = data;
- key = 0;
- for (i = 0; i < strlen (if_rmap->ifname); i++)
- key += if_rmap->ifname[i];
-
- return key;
+ return string_hash_make (if_rmap->ifname);
}
static int
diff --git a/lib/log.c b/lib/log.c
index 0c2f655b..df6e13db 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -653,6 +653,9 @@ closezlog (struct zlog *zl)
if (zl->fp != NULL)
fclose (zl->fp);
+ if (zl->filename != NULL)
+ free (zl->filename);
+
XFREE (MTYPE_ZLOG, zl);
}
diff --git a/lib/memory.c b/lib/memory.c
index dc09d8a6..4090fd90 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -58,7 +58,11 @@ zerror (const char *fname, int type, size_t size)
abort();
}
-/* Memory allocation. */
+/*
+ * Allocate memory of a given size, to be tracked by a given type.
+ * Effects: Returns a pointer to usable memory. If memory cannot
+ * be allocated, aborts execution.
+ */
void *
zmalloc (int type, size_t size)
{
@@ -74,7 +78,9 @@ zmalloc (int type, size_t size)
return memory;
}
-/* Memory allocation with num * size with cleared. */
+/*
+ * Allocate memory as in zmalloc, and also clear the memory.
+ */
void *
zcalloc (int type, size_t size)
{
@@ -90,7 +96,13 @@ zcalloc (int type, size_t size)
return memory;
}
-/* Memory reallocation. */
+/*
+ * Given a pointer returned by zmalloc or zcalloc, free it and
+ * return a pointer to a new size, basically acting like realloc().
+ * Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
+ * same type.
+ * Effects: Returns a pointer to the new memory, or aborts.
+ */
void *
zrealloc (int type, void *ptr, size_t size)
{
@@ -99,18 +111,34 @@ zrealloc (int type, void *ptr, size_t size)
memory = realloc (ptr, size);
if (memory == NULL)
zerror ("realloc", type, size);
+ if (ptr == NULL)
+ alloc_inc (type);
+
return memory;
}
-/* Memory free. */
+/*
+ * Free memory allocated by z*alloc or zstrdup.
+ * Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
+ * same type.
+ * Effects: The memory is freed and may no longer be referenced.
+ */
void
zfree (int type, void *ptr)
{
- alloc_dec (type);
- free (ptr);
+ if (ptr != NULL)
+ {
+ alloc_dec (type);
+ free (ptr);
+ }
}
-/* String duplication. */
+/*
+ * Duplicate a string, counting memory usage by type.
+ * Effects: The string is duplicated, and the return value must
+ * eventually be passed to zfree with the same type. The function will
+ * succeed or abort.
+ */
char *
zstrdup (int type, const char *str)
{
diff --git a/lib/memtypes.c b/lib/memtypes.c
index 05d93225..59020671 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -108,6 +108,7 @@ struct memory_list memory_list_bgp[] =
{ MTYPE_BGP_NODE, "BGP node" },
{ MTYPE_BGP_ROUTE, "BGP route" },
{ MTYPE_BGP_ROUTE_EXTRA, "BGP ancillary route info" },
+ { MTYPE_BGP_CONN, "BGP connected" },
{ MTYPE_BGP_STATIC, "BGP static" },
{ MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" },
{ MTYPE_BGP_ADVERTISE, "BGP adv" },
diff --git a/lib/prefix.c b/lib/prefix.c
index c85e6594..61a278ca 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -41,7 +41,7 @@ static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
/* Address Famiy Identifier to Address Family converter. */
int
-afi2family (int afi)
+afi2family (afi_t afi)
{
if (afi == AFI_IP)
return AF_INET;
@@ -52,7 +52,7 @@ afi2family (int afi)
return 0;
}
-int
+afi_t
family2afi (int family)
{
if (family == AF_INET)
@@ -70,15 +70,16 @@ prefix_match (const struct prefix *n, const struct prefix *p)
{
int offset;
int shift;
-
- /* Set both prefix's head pointer. */
- const u_char *np = (const u_char *)&n->u.prefix;
- const u_char *pp = (const u_char *)&p->u.prefix;
+ const u_char *np, *pp;
/* If n's prefix is longer than p's one return 0. */
if (n->prefixlen > p->prefixlen)
return 0;
+ /* Set both prefix's head pointer. */
+ np = (const u_char *)&n->u.prefix;
+ pp = (const u_char *)&p->u.prefix;
+
offset = n->prefixlen / PNBBY;
shift = n->prefixlen % PNBBY;
diff --git a/lib/prefix.h b/lib/prefix.h
index a7598b7e..5f1ff05c 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -144,8 +144,8 @@ prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
}
/* Prototypes. */
-extern int afi2family (int);
-extern int family2afi (int);
+extern int afi2family (afi_t);
+extern afi_t family2afi (int);
extern struct prefix *prefix_new (void);
extern void prefix_free (struct prefix *);
diff --git a/lib/sockunion.c b/lib/sockunion.c
index 6a40f332..a5382a72 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -527,6 +527,46 @@ sockopt_ttl (int family, int sock, int ttl)
return 0;
}
+int
+sockopt_cork (int sock, int onoff)
+{
+#ifdef TCP_CORK
+ return setsockopt (sock, IPPROTO_TCP, TCP_CORK, &onoff, sizeof(onoff));
+#else
+ return 0;
+#endif
+}
+
+int
+sockopt_minttl (int family, int sock, int minttl)
+{
+#ifdef IP_MINTTL
+ if (family == AF_INET)
+ {
+ int ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &minttl, sizeof(minttl));
+ if (ret < 0)
+ zlog (NULL, LOG_WARNING,
+ "can't set sockopt IP_MINTTL to %d on socket %d: %s",
+ minttl, sock, safe_strerror (errno));
+ return ret;
+ }
+#endif /* IP_MINTTL */
+#ifdef IPV6_MINHOPCNT
+ if (family == AF_INET6)
+ {
+ int ret = setsockopt (sock, IPPROTO_IPV6, IPV6_MINHOPCNT, &minttl, sizeof(minttl));
+ if (ret < 0)
+ zlog (NULL, LOG_WARNING,
+ "can't set sockopt IPV6_MINHOPCNT to %d on socket %d: %s",
+ minttl, sock, safe_strerror (errno));
+ return ret;
+ }
+#endif
+
+ errno = EOPNOTSUPP;
+ return -1;
+}
+
/* If same family and same prefix return 1. */
int
sockunion_same (union sockunion *su1, union sockunion *su2)
diff --git a/lib/sockunion.h b/lib/sockunion.h
index 96b9a0d4..0ee2d63b 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -102,6 +102,8 @@ extern int sockopt_reuseport (int);
extern int sockunion_bind (int sock, union sockunion *,
unsigned short, union sockunion *);
extern int sockopt_ttl (int family, int sock, int ttl);
+extern int sockopt_minttl (int family, int sock, int minttl);
+extern int sockopt_cork (int sock, int onoff);
extern int sockunion_socket (union sockunion *su);
extern const char *inet_sutop (union sockunion *su, char *str);
extern enum connect_result sockunion_connect (int fd, union sockunion *su,
diff --git a/lib/table.c b/lib/table.c
index 04df3af5..e40e6707 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -209,6 +209,10 @@ route_node_match (const struct route_table *table, const struct prefix *p)
{
if (node->info)
matched = node;
+
+ if (node->p.prefixlen == p->prefixlen)
+ break;
+
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
@@ -260,8 +264,8 @@ route_node_lookup (struct route_table *table, struct prefix *p)
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
- if (node->p.prefixlen == p->prefixlen && node->info)
- return route_lock_node (node);
+ if (node->p.prefixlen == p->prefixlen)
+ return node->info ? route_lock_node (node) : NULL;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
@@ -283,10 +287,8 @@ route_node_get (struct route_table *table, struct prefix *p)
prefix_match (&node->p, p))
{
if (node->p.prefixlen == p->prefixlen)
- {
- route_lock_node (node);
- return node;
- }
+ return route_lock_node (node);
+
match = node;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
diff --git a/lib/thread.c b/lib/thread.c
index e89af541..fd841c21 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -303,7 +303,7 @@ cpu_record_print(struct vty *vty, thread_type filter)
void *args[3] = {&tmp, vty, &filter};
memset(&tmp, 0, sizeof tmp);
- tmp.funcname = "TOTAL";
+ tmp.funcname = (char *)"TOTAL";
tmp.types = filter;
#ifdef HAVE_RUSAGE
@@ -382,6 +382,89 @@ DEFUN(show_thread_cpu,
cpu_record_print(vty, filter);
return CMD_SUCCESS;
}
+
+static void
+cpu_record_hash_clear (struct hash_backet *bucket,
+ void *args)
+{
+ thread_type *filter = args;
+ struct cpu_thread_history *a = bucket->data;
+
+ a = bucket->data;
+ if ( !(a->types & *filter) )
+ return;
+
+ hash_release (cpu_record, bucket->data);
+}
+
+static void
+cpu_record_clear (thread_type filter)
+{
+ thread_type *tmp = &filter;
+ hash_iterate (cpu_record,
+ (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
+ tmp);
+}
+
+DEFUN(clear_thread_cpu,
+ clear_thread_cpu_cmd,
+ "clear thread cpu [FILTER]",
+ "Clear stored data\n"
+ "Thread information\n"
+ "Thread CPU usage\n"
+ "Display filter (rwtexb)\n")
+{
+ int i = 0;
+ thread_type filter = (thread_type) -1U;
+
+ if (argc > 0)
+ {
+ filter = 0;
+ while (argv[0][i] != '\0')
+ {
+ switch ( argv[0][i] )
+ {
+ case 'r':
+ case 'R':
+ filter |= (1 << THREAD_READ);
+ break;
+ case 'w':
+ case 'W':
+ filter |= (1 << THREAD_WRITE);
+ break;
+ case 't':
+ case 'T':
+ filter |= (1 << THREAD_TIMER);
+ break;
+ case 'e':
+ case 'E':
+ filter |= (1 << THREAD_EVENT);
+ break;
+ case 'x':
+ case 'X':
+ filter |= (1 << THREAD_EXECUTE);
+ break;
+ case 'b':
+ case 'B':
+ filter |= (1 << THREAD_BACKGROUND);
+ break;
+ default:
+ break;
+ }
+ ++i;
+ }
+ if (filter == 0)
+ {
+ vty_out(vty, "Invalid filter \"%s\" specified,"
+ " must contain at least one of 'RWTEXB'%s",
+ argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ cpu_record_clear (filter);
+ return CMD_SUCCESS;
+}
/* List allocation and head/tail print out. */
static void
@@ -903,6 +986,24 @@ thread_timer_process (struct thread_list *list, struct timeval *timenow)
return ready;
}
+/* process a list en masse, e.g. for event thread lists */
+static unsigned int
+thread_process (struct thread_list *list)
+{
+ struct thread *thread;
+ unsigned int ready = 0;
+
+ for (thread = list->head; thread; thread = thread->next)
+ {
+ thread_list_delete (list, thread);
+ thread->type = THREAD_READY;
+ thread_list_add (&thread->master->ready, thread);
+ ready++;
+ }
+ return ready;
+}
+
+
/* Fetch next ready thread. */
struct thread *
thread_fetch (struct thread_master *m, struct thread *fetch)
@@ -911,41 +1012,48 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
fd_set readfd;
fd_set writefd;
fd_set exceptfd;
- struct timeval timer_val;
+ struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 };
struct timeval timer_val_bg;
- struct timeval *timer_wait;
+ struct timeval *timer_wait = &timer_val;
struct timeval *timer_wait_bg;
while (1)
{
int num = 0;
- /* Signals are highest priority */
+ /* Signals pre-empt everything */
quagga_sigevent_process ();
- /* Normal event are the next highest priority. */
- if ((thread = thread_trim_head (&m->event)) != NULL)
- return thread_run (m, thread, fetch);
-
- /* If there are any ready threads from previous scheduler runs,
- * process top of them.
+ /* Drain the ready queue of already scheduled jobs, before scheduling
+ * more.
*/
if ((thread = thread_trim_head (&m->ready)) != NULL)
return thread_run (m, thread, fetch);
+ /* To be fair to all kinds of threads, and avoid starvation, we
+ * need to be careful to consider all thread types for scheduling
+ * in each quanta. I.e. we should not return early from here on.
+ */
+
+ /* Normal event are the next highest priority. */
+ thread_process (&m->event);
+
/* Structure copy. */
readfd = m->readfd;
writefd = m->writefd;
exceptfd = m->exceptfd;
/* Calculate select wait timer if nothing else to do */
- quagga_get_relative (NULL);
- timer_wait = thread_timer_wait (&m->timer, &timer_val);
- timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
-
- if (timer_wait_bg &&
- (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
- timer_wait = timer_wait_bg;
+ if (m->ready.count == 0)
+ {
+ quagga_get_relative (NULL);
+ timer_wait = thread_timer_wait (&m->timer, &timer_val);
+ timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
+
+ if (timer_wait_bg &&
+ (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
+ timer_wait = timer_wait_bg;
+ }
num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
diff --git a/lib/thread.h b/lib/thread.h
index b52bc541..978aa6b0 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -82,7 +82,7 @@ struct thread
struct cpu_thread_history
{
int (*func)(struct thread *);
- const char *funcname;
+ char *funcname;
unsigned int total_calls;
struct time_stats
{
@@ -197,6 +197,7 @@ extern int thread_should_yield (struct thread *);
/* Internal libzebra exports */
extern void thread_getrusage (RUSAGE_T *);
extern struct cmd_element show_thread_cpu_cmd;
+extern struct cmd_element clear_thread_cpu_cmd;
/* replacements for the system gettimeofday(), clock_gettime() and
* time() functions, providing support for non-decrementing clock on
diff --git a/lib/vty.c b/lib/vty.c
index e4818eb6..bd1dbac0 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -250,7 +250,7 @@ vty_hello (struct vty *vty)
vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
}
else if (host.motd)
- vty_out (vty, host.motd);
+ vty_out (vty, "%s", host.motd);
}
/* Put out prompt and wait input from user. */
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 7c811edd..52b5f41c 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -341,7 +341,7 @@ work_queue_run (struct thread *thread)
stats:
-#define WQ_HYSTERIS_FACTOR 2
+#define WQ_HYSTERESIS_FACTOR 4
/* we yielded, check whether granularity should be reduced */
if (yielded && (cycles < wq->cycles.granularity))
@@ -349,17 +349,18 @@ stats:
wq->cycles.granularity = ((cycles > 0) ? cycles
: WORK_QUEUE_MIN_GRANULARITY);
}
-
- if (cycles >= (wq->cycles.granularity))
+ /* otherwise, should granularity increase? */
+ else if (cycles >= (wq->cycles.granularity))
{
if (cycles > wq->cycles.best)
wq->cycles.best = cycles;
- /* along with yielded check, provides hysteris for granularity */
- if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR * 2))
- wq->cycles.granularity *= WQ_HYSTERIS_FACTOR; /* quick ramp-up */
- else if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR))
- wq->cycles.granularity += WQ_HYSTERIS_FACTOR;
+ /* along with yielded check, provides hysteresis for granularity */
+ if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR
+ * WQ_HYSTERESIS_FACTOR))
+ wq->cycles.granularity *= WQ_HYSTERESIS_FACTOR; /* quick ramp-up */
+ else if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR))
+ wq->cycles.granularity += WQ_HYSTERESIS_FACTOR;
}
#undef WQ_HYSTERIS_FACTOR
diff --git a/lib/zclient.c b/lib/zclient.c
index d3d53227..52a3627d 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -339,12 +339,12 @@ zclient_start (struct zclient *zclient)
/* Create read thread. */
zclient_event (ZCLIENT_READ, zclient);
- /* We need interface information. */
- zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
-
/* We need router-id information. */
zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
+ /* We need interface information. */
+ zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
+
/* Flush all redistribute request. */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default && zclient->redist[i])
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 3c999bbc..f4b327e4 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -199,14 +199,10 @@ ospf6_area_delete (struct ospf6_area *oa)
ospf6_lsdb_delete (oa->lsdb);
ospf6_lsdb_delete (oa->lsdb_self);
+ ospf6_spf_table_finish (oa->spf_table);
ospf6_route_table_delete (oa->spf_table);
ospf6_route_table_delete (oa->route_table);
-#if 0
- ospf6_spftree_delete (oa->spf_tree);
- ospf6_route_table_delete (oa->topology_table);
-#endif /*0*/
-
THREAD_OFF (oa->thread_spf_calculation);
THREAD_OFF (oa->thread_route_calculation);
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 685b147c..3efaab44 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -1219,6 +1219,11 @@ ospf6_asbr_init (void)
install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
}
+void
+ospf6_asbr_terminate (void)
+{
+ route_map_finish ();
+}
DEFUN (debug_ospf6_asbr,
debug_ospf6_asbr_cmd,
diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h
index 7166aa3e..6deb93ef 100644
--- a/ospf6d/ospf6_asbr.h
+++ b/ospf6d/ospf6_asbr.h
@@ -79,6 +79,7 @@ extern void ospf6_asbr_redistribute_remove (int type, int ifindex,
extern int ospf6_redistribute_config_write (struct vty *vty);
extern void ospf6_asbr_init (void);
+extern void ospf6_asbr_terminate (void);
extern int config_write_ospf6_debug_asbr (struct vty *vty);
extern void install_element_ospf6_debug_asbr (void);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index cb347451..236baf17 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -118,6 +118,7 @@ ospf6_interface_create (struct interface *ifp)
oi->cost = 1;
oi->state = OSPF6_INTERFACE_DOWN;
oi->flag = 0;
+ oi->mtu_ignore = 0;
/* Try to adjust I/O buffer size with IfMtu */
oi->ifmtu = ifp->mtu6;
@@ -784,6 +785,8 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
{
vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s",
oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
+ vty_out (vty, " MTU mismatch detection: %s%s", oi->mtu_ignore ?
+ "disabled" : "enabled", VNL);
inet_ntop (AF_INET, &oi->area->area_id,
strbuf, sizeof (strbuf));
vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, oi->cost,
@@ -1368,6 +1371,55 @@ DEFUN (no_ipv6_ospf6_passive,
return CMD_SUCCESS;
}
+DEFUN (ipv6_ospf6_mtu_ignore,
+ ipv6_ospf6_mtu_ignore_cmd,
+ "ipv6 ospf6 mtu-ignore",
+ IP6_STR
+ OSPF6_STR
+ "Ignore MTU mismatch on this interface\n"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL)
+ oi = ospf6_interface_create (ifp);
+ assert (oi);
+
+ oi->mtu_ignore = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_ospf6_mtu_ignore,
+ no_ipv6_ospf6_mtu_ignore_cmd,
+ "no ipv6 ospf6 mtu-ignore",
+ NO_STR
+ IP6_STR
+ OSPF6_STR
+ "Ignore MTU mismatch on this interface\n"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL)
+ oi = ospf6_interface_create (ifp);
+ assert (oi);
+
+ oi->mtu_ignore = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ipv6_ospf6_advertise_prefix_list,
ipv6_ospf6_advertise_prefix_list_cmd,
"ipv6 ospf6 advertise prefix-list WORD",
@@ -1495,6 +1547,9 @@ config_write_ospf6_interface (struct vty *vty)
if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
vty_out (vty, " ipv6 ospf6 passive%s", VNL);
+ if (oi->mtu_ignore)
+ vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
+
vty_out (vty, "!%s", VNL);
}
return 0;
@@ -1547,6 +1602,9 @@ ospf6_interface_init (void)
install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
+ install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
+ install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
+
install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
}
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 878c29e2..cf758c07 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -76,6 +76,9 @@ struct ospf6_interface
/* OSPF6 Interface flag */
char flag;
+ /* MTU mismatch check */
+ u_char mtu_ignore;
+
/* Decision of DR Election */
u_int32_t drouter;
u_int32_t bdrouter;
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 05b11ba3..9bc603b3 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1177,6 +1177,8 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
}
ospf6_route_remove (route, oa->route_table);
}
+ if (route)
+ ospf6_route_unlock (route);
}
if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index c1db3741..588b9462 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -712,6 +712,11 @@ ospf6_lsa_init (void)
ospf6_install_lsa_handler (&unknown_handler);
}
+void
+ospf6_lsa_terminate (void)
+{
+ vector_free (ospf6_lsa_handler_vector);
+}
static char *
ospf6_lsa_handler_name (struct ospf6_lsa_handler *h)
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index fb0f27cd..c1093cab 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -243,6 +243,7 @@ extern void ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler);
extern struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type);
extern void ospf6_lsa_init (void);
+extern void ospf6_lsa_terminate (void);
extern void ospf6_lsa_cmd_init (void);
extern int config_write_ospf6_debug_lsa (struct vty *vty);
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index a7a96a1f..800fae4b 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -124,6 +124,35 @@ Report bugs to zebra@zebra.org\n", progname);
exit (status);
}
+static void
+ospf6_exit (int status)
+{
+ extern struct ospf6 *ospf6;
+ extern struct zclient *zclient;
+
+ if (ospf6)
+ ospf6_delete (ospf6);
+
+ ospf6_message_terminate ();
+ ospf6_asbr_terminate ();
+ ospf6_lsa_terminate ();
+
+ if_terminate ();
+ vty_terminate ();
+ cmd_terminate ();
+
+ if (zclient)
+ zclient_free (zclient);
+
+ if (master)
+ thread_master_free (master);
+
+ if (zlog_default)
+ closezlog (zlog_default);
+
+ exit (status);
+}
+
/* SIGHUP handler. */
static void
sighup (void)
@@ -136,7 +165,7 @@ static void
sigint (void)
{
zlog_notice ("Terminating on signal SIGINT");
- exit (0);
+ ospf6_exit (0);
}
/* SIGTERM handler. */
@@ -144,7 +173,7 @@ static void
sigterm (void)
{
zlog_notice ("Terminating on signal SIGTERM");
- exit (0);
+ ospf6_exit (0);
}
/* SIGUSR1 handler. */
@@ -308,7 +337,7 @@ main (int argc, char *argv[], char *envp[])
zlog_warn ("Thread failed");
/* Not reached. */
- exit (0);
+ ospf6_exit (0);
}
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 790fc0ae..51933b76 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -832,7 +832,7 @@ ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
((caddr_t) oh + sizeof (struct ospf6_header));
/* Interface MTU check */
- if (ntohs (dbdesc->ifmtu) != oi->ifmtu)
+ if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("I/F MTU mismatch");
@@ -1168,6 +1168,24 @@ ospf6_iobuf_size (unsigned int size)
return iobuflen;
}
+void
+ospf6_message_terminate (void)
+{
+ if (recvbuf)
+ {
+ XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
+ recvbuf = NULL;
+ }
+
+ if (sendbuf)
+ {
+ XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
+ sendbuf = NULL;
+ }
+
+ iobuflen = 0;
+}
+
int
ospf6_receive (struct thread *thread)
{
diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h
index ebb6308e..c72f0af4 100644
--- a/ospf6d/ospf6_message.h
+++ b/ospf6d/ospf6_message.h
@@ -123,6 +123,7 @@ extern void ospf6_lsupdate_print (struct ospf6_header *);
extern void ospf6_lsack_print (struct ospf6_header *);
extern int ospf6_iobuf_size (unsigned int size);
+extern void ospf6_message_terminate (void);
extern int ospf6_receive (struct thread *thread);
extern int ospf6_hello_send (struct thread *thread);
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 1e1f4fb5..398acfa8 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -690,6 +690,8 @@ ospf6_route_best_next (struct ospf6_route *route)
struct route_node *rnode;
struct ospf6_route *next;
+ ospf6_route_unlock (route);
+
rnode = route->rnode;
route_lock_node (rnode);
rnode = route_next (rnode);
@@ -701,7 +703,6 @@ ospf6_route_best_next (struct ospf6_route *route)
assert (rnode->info);
next = (struct ospf6_route *) rnode->info;
- ospf6_route_unlock (route);
ospf6_route_lock (next);
return next;
}
@@ -1335,13 +1336,14 @@ ospf6_brouter_show (struct vty *vty, struct ospf6_route *route)
DEFUN (debug_ospf6_route,
debug_ospf6_route_cmd,
- "debug ospf6 route (table|intra-area|inter-area)",
+ "debug ospf6 route (table|intra-area|inter-area|memory)",
DEBUG_STR
OSPF6_STR
"Debug route table calculation\n"
"Debug detail\n"
"Debug intra-area route calculation\n"
"Debug inter-area route calculation\n"
+ "Debug route memory use\n"
)
{
unsigned char level = 0;
@@ -1352,18 +1354,21 @@ DEFUN (debug_ospf6_route,
level = OSPF6_DEBUG_ROUTE_INTRA;
else if (! strncmp (argv[0], "inter", 5))
level = OSPF6_DEBUG_ROUTE_INTER;
+ else if (! strncmp (argv[0], "memor", 5))
+ level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_ON (level);
return CMD_SUCCESS;
}
DEFUN (no_debug_ospf6_route,
no_debug_ospf6_route_cmd,
- "no debug ospf6 route (table|intra-area|inter-area)",
+ "no debug ospf6 route (table|intra-area|inter-area|memory)",
NO_STR
DEBUG_STR
OSPF6_STR
"Debug route table calculation\n"
- "Debug intra-area route calculation\n")
+ "Debug intra-area route calculation\n"
+ "Debug route memory use\n")
{
unsigned char level = 0;
@@ -1373,6 +1378,8 @@ DEFUN (no_debug_ospf6_route,
level = OSPF6_DEBUG_ROUTE_INTRA;
else if (! strncmp (argv[0], "inter", 5))
level = OSPF6_DEBUG_ROUTE_INTER;
+ else if (! strncmp (argv[0], "memor", 5))
+ level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_OFF (level);
return CMD_SUCCESS;
}
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index bfb6df2e..cb549618 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -50,7 +50,9 @@ ospf6_vertex_cmp (void *a, void *b)
struct ospf6_vertex *vb = (struct ospf6_vertex *) b;
/* ascending order */
- return (va->cost - vb->cost);
+ if (va->cost != vb->cost)
+ return (va->cost - vb->cost);
+ return (va->hops - vb->hops);
}
static int
@@ -320,22 +322,8 @@ ospf6_spf_install (struct ospf6_vertex *v,
}
prev = (struct ospf6_vertex *) route->route_option;
- if (prev->hops > v->hops)
- {
- for (ALL_LIST_ELEMENTS (prev->child_list, node, nnode, w))
- {
- assert (w->parent == prev);
- w->parent = v;
- listnode_add_sort (v->child_list, w);
- }
- listnode_delete (prev->parent->child_list, prev);
- listnode_add_sort (v->parent->child_list, v);
-
- ospf6_vertex_delete (prev);
- route->route_option = v;
- }
- else
- ospf6_vertex_delete (v);
+ assert (prev->hops <= v->hops);
+ ospf6_vertex_delete (v);
return -1;
}
@@ -404,18 +392,19 @@ ospf6_spf_calculation (u_int32_t router_id,
caddr_t lsdesc;
struct ospf6_lsa *lsa;
- /* initialize */
- candidate_list = pqueue_create ();
- candidate_list->cmp = ospf6_vertex_cmp;
-
- ospf6_spf_table_finish (result_table);
-
/* Install the calculating router itself as the root of the SPF tree */
/* construct root vertex */
lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_ROUTER), htonl (0),
router_id, oa->lsdb);
if (lsa == NULL)
return;
+
+ /* initialize */
+ candidate_list = pqueue_create ();
+ candidate_list->cmp = ospf6_vertex_cmp;
+
+ ospf6_spf_table_finish (result_table);
+
root = ospf6_vertex_create (lsa);
root->area = oa;
root->cost = 0;
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 82370268..2b65be82 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -51,6 +51,8 @@
/* global ospf6d variable */
struct ospf6 *ospf6;
+static void ospf6_disable (struct ospf6 *o);
+
static void
ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
{
@@ -143,15 +145,17 @@ ospf6_create (void)
return o;
}
-#if 0
-static void
+void
ospf6_delete (struct ospf6 *o)
{
struct listnode *node, *nnode;
struct ospf6_area *oa;
+ ospf6_disable (ospf6);
+
for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
ospf6_area_delete (oa);
+ list_delete (o->area_list);
ospf6_lsdb_delete (o->lsdb);
ospf6_lsdb_delete (o->lsdb_self);
@@ -164,7 +168,6 @@ ospf6_delete (struct ospf6 *o)
XFREE (MTYPE_OSPF6_TOP, o);
}
-#endif
static void
ospf6_enable (struct ospf6 *o)
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index ba485f9e..4b2d2c3e 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -69,6 +69,7 @@ extern struct ospf6 *ospf6;
/* prototypes */
extern void ospf6_top_init (void);
+extern void ospf6_delete (struct ospf6 *o);
extern void ospf6_maxage_remove (struct ospf6 *o);
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 0a8ac3e4..881771a7 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -132,6 +132,9 @@ ospf6_zebra_if_state_update (int command, struct zclient *zclient,
struct interface *ifp;
ifp = zebra_interface_state_read (zclient->ibuf);
+ if (ifp == NULL)
+ return 0;
+
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
zlog_debug ("Zebra Interface state change: "
"%s index %d flags %llx metric %d mtu %d",
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 7e32195b..7a75194a 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -565,8 +565,7 @@ ospf_check_abr_status (struct ospf *ospf)
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags);
ospf->flags = new_flags;
- OSPF_TIMER_ON (ospf->t_router_lsa_update,
- ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+ ospf_router_lsa_update (ospf);
}
}
@@ -760,7 +759,7 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
zlog_debug ("ospf_abr_announce_network_to_area(): "
"refreshing summary");
set_metric (old, cost);
- lsa = ospf_summary_lsa_refresh (area->ospf, old);
+ lsa = ospf_lsa_refresh (area->ospf, old);
if (!lsa)
{
@@ -1148,7 +1147,7 @@ ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
if (old)
{
set_metric (old, cost);
- lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
+ lsa = ospf_lsa_refresh (area->ospf, old);
}
else
lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c
index 77383191..fc3b51dd 100644
--- a/ospfd/ospf_api.c
+++ b/ospfd/ospf_api.c
@@ -219,7 +219,7 @@ msg_print (struct msg *msg)
#else /* ORIGINAL_CODING */
/* API message common header part. */
zlog_debug
- ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%lu)",
+ ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",
ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype,
ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq),
STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index 15fd2e5f..2a9003b7 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -1831,7 +1831,7 @@ ospf_apiserver_lsa11_originator (void *arg)
/* Periodically refresh opaque LSAs so that they do not expire in
other routers. */
-void
+struct ospf_lsa *
ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)
{
struct ospf_apiserver *apiserv;
@@ -1904,7 +1904,7 @@ ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)
}
out:
- return;
+ return new;
}
diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h
index 9a8ae254..b60f56b4 100644
--- a/ospfd/ospf_apiserver.h
+++ b/ospfd/ospf_apiserver.h
@@ -180,7 +180,7 @@ extern void ospf_apiserver_config_write_router (struct vty *vty);
extern void ospf_apiserver_config_write_if (struct vty *vty, struct interface *ifp);
extern void ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa);
extern int ospf_ospf_apiserver_lsa_originator (void *arg);
-extern void ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa);
+extern struct ospf_lsa *ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa);
extern void ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv,
u_char lsa_type, u_char opaque_type);
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 6f1b0b06..c39efee1 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -264,8 +264,7 @@ ospf_asbr_status_update (struct ospf *ospf, u_char status)
/* Transition from/to status ASBR, schedule timer. */
ospf_spf_calculate_schedule (ospf);
- OSPF_TIMER_ON (ospf->t_router_lsa_update,
- ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+ ospf_router_lsa_update (ospf);
}
void
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index 5d0cae42..3c199311 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -451,8 +451,8 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa)
/* if there is a Intra/Inter area route to the N
do not install external route */
- if (rn = route_node_lookup (ospf->new_table,
- (struct prefix *) &p))
+ if ((rn = route_node_lookup (ospf->new_table,
+ (struct prefix *) &p)))
{
route_unlock_node(rn);
if (rn->info == NULL)
@@ -463,8 +463,8 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa)
}
/* Find a route to the same dest */
/* If there is no route, create new one. */
- if (rn = route_node_lookup (ospf->new_external_route,
- (struct prefix *) &p))
+ if ((rn = route_node_lookup (ospf->new_external_route,
+ (struct prefix *) &p)))
route_unlock_node(rn);
if (!rn || (or = rn->info) == NULL)
@@ -718,7 +718,6 @@ ospf_ase_register_external_lsa (struct ospf_lsa *lsa, struct ospf *top)
/* We assume that if LSA is deleted from DB
is is also deleted from this RT */
-
listnode_add (lst, ospf_lsa_lock (lsa)); /* external_lsas lst */
}
@@ -799,7 +798,8 @@ ospf_ase_incremental_update (struct ospf *ospf, struct ospf_lsa *lsa)
}
rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p);
- assert (rn && rn->info);
+ assert (rn);
+ assert (rn->info);
lsas = rn->info;
route_unlock_node (rn);
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 41661da2..77f2e161 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -135,7 +135,7 @@ ospf_process_self_originated_lsa (struct ospf *ospf,
/* Originate a new instance and schedule flooding */
if (area->router_lsa_self)
area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
return;
case OSPF_NETWORK_LSA:
#ifdef HAVE_OPAQUE_LSA
@@ -171,7 +171,7 @@ ospf_process_self_originated_lsa (struct ospf *ospf,
if (oi->network_lsa_self)
oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
/* Schedule network-LSA origination. */
- ospf_network_lsa_timer_add (oi);
+ ospf_network_lsa_update (oi);
return;
}
break;
@@ -991,3 +991,33 @@ ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)
ospf_flood_through_as (ospf, NULL, lsa);
ospf_lsa_maxage (ospf, lsa);
}
+
+void
+ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa)
+{
+ lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
+
+ switch (lsa->data->type)
+ {
+ case OSPF_ROUTER_LSA:
+ case OSPF_NETWORK_LSA:
+ case OSPF_SUMMARY_LSA:
+ case OSPF_ASBR_SUMMARY_LSA:
+ case OSPF_AS_NSSA_LSA:
+#ifdef HAVE_OPAQUE_LSA
+ case OSPF_OPAQUE_LINK_LSA:
+ case OSPF_OPAQUE_AREA_LSA:
+#endif /* HAVE_OPAQUE_LSA */
+ ospf_lsa_flush_area (lsa, lsa->area);
+ break;
+ case OSPF_AS_EXTERNAL_LSA:
+#ifdef HAVE_OPAQUE_LSA
+ case OSPF_OPAQUE_AS_LSA:
+#endif /* HAVE_OPAQUE_LSA */
+ ospf_lsa_flush_as (ospf, lsa);
+ break;
+ default:
+ zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type);
+ break;
+ }
+}
diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h
index 5382e8fe..1ab11b88 100644
--- a/ospfd/ospf_flood.h
+++ b/ospfd/ospf_flood.h
@@ -66,6 +66,7 @@ extern void ospf_flood_lsa_area (struct ospf_lsa *, struct ospf_area *);
extern void ospf_flood_lsa_as (struct ospf_lsa *);
extern void ospf_lsa_flush_area (struct ospf_lsa *, struct ospf_area *);
extern void ospf_lsa_flush_as (struct ospf *, struct ospf_lsa *);
+extern void ospf_lsa_flush (struct ospf *, struct ospf_lsa *);
extern struct external_info *ospf_external_info_check (struct ospf_lsa *);
extern void ospf_lsdb_init (struct ospf_lsdb *);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index afe3acf1..dc0787d5 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -97,7 +97,7 @@ ospf_if_recalculate_output_cost (struct interface *ifp)
if (oi->output_cost != newcost)
{
oi->output_cost = newcost;
- ospf_router_lsa_timer_add (oi->area);
+ ospf_router_lsa_update_area (oi->area);
}
}
}
@@ -219,9 +219,6 @@ ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
ospf_add_to_if (ifp, oi);
listnode_add (ospf->oiflist, oi);
- /* Clear self-originated network-LSA. */
- oi->network_lsa_self = NULL;
-
/* Initialize neighbor list. */
oi->nbrs = route_table_init ();
@@ -301,10 +298,6 @@ ospf_if_cleanup (struct ospf_interface *oi)
ospf_nbr_delete (oi->nbr_self);
oi->nbr_self = ospf_nbr_new (oi);
ospf_nbr_add_self (oi);
-
- ospf_lsa_unlock (&oi->network_lsa_self);
- oi->network_lsa_self = NULL;
- OSPF_TIMER_OFF (oi->t_network_lsa_self);
}
void
@@ -335,6 +328,8 @@ ospf_if_free (struct ospf_interface *oi)
listnode_delete (oi->ospf->oiflist, oi);
listnode_delete (oi->area->oiflist, oi);
+ thread_cancel_event (master, oi);
+
memset (oi, 0, sizeof (*oi));
XFREE (MTYPE_OSPF_IF, oi);
}
@@ -534,6 +529,8 @@ ospf_new_if_params (void)
oip->auth_crypt = list_new ();
+ oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
+
return oip;
}
@@ -572,7 +569,8 @@ ospf_free_if_params (struct interface *ifp, struct in_addr addr)
!OSPF_IF_PARAM_CONFIGURED (oip, type) &&
!OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
!OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
- listcount (oip->auth_crypt) == 0)
+ listcount (oip->auth_crypt) == 0 &&
+ ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
{
ospf_del_if_params (oip);
rn->info = NULL;
@@ -1121,8 +1119,8 @@ ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
zlog_debug ("ospf_vl_up_check: VL cost change,"
" scheduling router lsa refresh");
- if(ospf->backbone)
- ospf_router_lsa_timer_add (ospf->backbone);
+ if (ospf->backbone)
+ ospf_router_lsa_update_area (ospf->backbone);
else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
}
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index ab0b7580..6db88773 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -73,6 +73,9 @@ struct ospf_if_params
DECLARE_IF_PARAM (struct list *, auth_crypt); /* List of Auth cryptographic data. */
DECLARE_IF_PARAM (int, auth_type); /* OSPF authentication type */
+
+ /* Other, non-configuration state */
+ u_int32_t network_lsa_seqnum; /* Network LSA seqnum */
};
enum
@@ -167,6 +170,7 @@ struct ospf_interface
/* Configured varables. */
struct ospf_if_params *params;
+
u_int32_t crypt_seqnum; /* Cryptographic Sequence Number */
u_int32_t output_cost; /* Acutual Interface Output Cost */
@@ -206,8 +210,6 @@ struct ospf_interface
struct thread *t_ls_ack; /* timer */
struct thread *t_ls_ack_direct; /* event */
struct thread *t_ls_upd_event; /* event */
- struct thread *t_network_lsa_self; /* self-originated network-LSA
- reflesh thread. timer */
#ifdef HAVE_OPAQUE_LSA
struct thread *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */
#endif /* HAVE_OPAQUE_LSA */
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index 18402836..db53882d 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -221,8 +221,8 @@ ospf_dr_election (struct ospf_interface *oi)
new_state = ospf_ism_state (oi);
- zlog_info ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi)));
- zlog_info ("DR-Election[1st]: DR %s", inet_ntoa (DR (oi)));
+ zlog_debug ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi)));
+ zlog_debug ("DR-Election[1st]: DR %s", inet_ntoa (DR (oi)));
if (new_state != old_state &&
!(new_state == ISM_DROther && old_state < ISM_DROther))
@@ -232,8 +232,8 @@ ospf_dr_election (struct ospf_interface *oi)
new_state = ospf_ism_state (oi);
- zlog_info ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi)));
- zlog_info ("DR-Election[2nd]: DR %s", inet_ntoa (DR (oi)));
+ zlog_debug ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi)));
+ zlog_debug ("DR-Election[2nd]: DR %s", inet_ntoa (DR (oi)));
}
list_delete (el_list);
@@ -578,20 +578,17 @@ ism_change_state (struct ospf_interface *oi, int state)
oi->area->act_ints++;
/* schedule router-LSA originate. */
- ospf_router_lsa_timer_add (oi->area);
+ ospf_router_lsa_update_area (oi->area);
/* Originate network-LSA. */
if (old_state != ISM_DR && state == ISM_DR)
- ospf_network_lsa_timer_add (oi);
+ ospf_network_lsa_update (oi);
else if (old_state == ISM_DR && state != ISM_DR)
{
/* Free self originated network LSA. */
lsa = oi->network_lsa_self;
if (lsa)
- {
- ospf_lsa_flush_area (lsa, oi->area);
- OSPF_TIMER_OFF (oi->t_network_lsa_self);
- }
+ ospf_lsa_flush_area (lsa, oi->area);
ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = NULL;
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index e708d5e2..842df49c 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -372,7 +372,7 @@ lsa_header_set (struct stream *s, u_char options,
lsah = (struct lsa_header *) STREAM_DATA (s);
- lsah->ls_age = htons (0);
+ lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
lsah->options = options;
lsah->type = type;
lsah->id = id;
@@ -741,7 +741,7 @@ ospf_stub_router_timer (struct thread *t)
UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
return 0;
}
@@ -885,6 +885,9 @@ ospf_router_lsa_refresh (struct ospf_lsa *lsa)
/* Delete LSA from neighbor retransmit-list. */
ospf_ls_retransmit_delete_nbr_area (area, lsa);
+ /* Unregister LSA from refresh-list */
+ ospf_refresher_unregister_lsa (area->ospf, lsa);
+
/* Create new router-LSA instance. */
if ( (new = ospf_router_lsa_new (area)) == NULL)
{
@@ -910,20 +913,15 @@ ospf_router_lsa_refresh (struct ospf_lsa *lsa)
return NULL;
}
-static int
-ospf_router_lsa_timer (struct thread *t)
+int
+ospf_router_lsa_update_area (struct ospf_area *area)
{
- struct ospf_area *area;
-
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
-
- area = THREAD_ARG (t);
- area->t_router_lsa_self = NULL;
+ zlog_debug ("[router-LSA]: (router-LSA area update)");
/* Now refresh router-LSA. */
if (area->router_lsa_self)
- ospf_router_lsa_refresh (area->router_lsa_self);
+ ospf_lsa_refresh (area->ospf, area->router_lsa_self);
/* Newly originate router-LSA. */
else
ospf_router_lsa_originate (area);
@@ -931,50 +929,15 @@ ospf_router_lsa_timer (struct thread *t)
return 0;
}
-void
-ospf_router_lsa_timer_add (struct ospf_area *area)
-{
- /* Keep area's self-originated router-LSA. */
- struct ospf_lsa *lsa = area->router_lsa_self;
-
- /* Cancel previously scheduled router-LSA timer. */
- if (area->t_router_lsa_self)
- if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
- zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
-
- OSPF_TIMER_OFF (area->t_router_lsa_self);
-
- /* If router-LSA is originated previously, check the interval time. */
- if (lsa)
- {
- int delay;
- if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
- {
- OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
- ospf_router_lsa_timer, delay);
- return;
- }
- }
-
- if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
- zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
-
- /* Immediately refresh router-LSA. */
- OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
-}
-
int
-ospf_router_lsa_update_timer (struct thread *thread)
+ospf_router_lsa_update (struct ospf *ospf)
{
- struct ospf *ospf = THREAD_ARG (thread);
struct listnode *node, *nnode;
struct ospf_area *area;
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
zlog_debug ("Timer[router-LSA Update]: (timer expire)");
- ospf->t_router_lsa_update = NULL;
-
for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
{
struct ospf_lsa *lsa = area->router_lsa_self;
@@ -999,19 +962,20 @@ ospf_router_lsa_update_timer (struct thread *thread)
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
lsa->data->type, inet_ntoa (lsa->data->id), area_str);
+ ospf_refresher_unregister_lsa (ospf, lsa);
ospf_lsa_flush_area (lsa, area);
ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = NULL;
/* Refresh router-LSA, (not install) and flood through area. */
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
}
else
{
rl = (struct router_lsa *) lsa->data;
/* Refresh router-LSA, (not install) and flood through area. */
if (rl->flags != ospf->flags)
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
}
}
@@ -1048,6 +1012,7 @@ ospf_network_lsa_new (struct ospf_interface *oi)
struct stream *s;
struct ospf_lsa *new;
struct lsa_header *lsah;
+ struct ospf_if_params *oip;
int length;
/* If there are no neighbours on this network (the net is stub),
@@ -1086,20 +1051,42 @@ ospf_network_lsa_new (struct ospf_interface *oi)
new->data = ospf_lsa_data_new (length);
memcpy (new->data, lsah, length);
stream_free (s);
-
+
+ /* Remember prior network LSA sequence numbers, even if we stop
+ * originating one for this oi, to try avoid re-originating LSAs with a
+ * prior sequence number, and thus speed up adjency forming & convergence.
+ */
+ if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
+ {
+ new->data->ls_seqnum = oip->network_lsa_seqnum;
+ new->data->ls_seqnum = lsa_seqnum_increment (new);
+ }
+ else
+ {
+ oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
+ ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
+ }
+ oip->network_lsa_seqnum = new->data->ls_seqnum;
+
return new;
}
/* Originate network-LSA. */
-static struct ospf_lsa *
-ospf_network_lsa_originate (struct ospf_interface *oi)
+void
+ospf_network_lsa_update (struct ospf_interface *oi)
{
struct ospf_lsa *new;
-
+
+ if (oi->network_lsa_self != NULL)
+ {
+ ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
+ return;
+ }
+
/* Create new network-LSA instance. */
new = ospf_network_lsa_new (oi);
if (new == NULL)
- return NULL;
+ return;
/* Install LSA to LSDB. */
new = ospf_lsa_install (oi->ospf, oi, new);
@@ -1117,28 +1104,51 @@ ospf_network_lsa_originate (struct ospf_interface *oi)
ospf_lsa_header_dump (new->data);
}
- return new;
+ return;
}
-int
-ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
+static struct ospf_lsa *
+ospf_network_lsa_refresh (struct ospf_lsa *lsa)
{
struct ospf_area *area = lsa->area;
- struct ospf_lsa *new;
-
+ struct ospf_lsa *new, *new2;
+ struct ospf_if_params *oip;
+ struct ospf_interface *oi;
+
assert (lsa->data);
-
+
+ /* Retrieve the oi for the network LSA */
+ oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
+ if (oi == NULL)
+ {
+ if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
+ {
+ zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
+ "no oi found, ick, ignoring.",
+ lsa->data->type, inet_ntoa (lsa->data->id));
+ ospf_lsa_header_dump (lsa->data);
+ }
+ return NULL;
+ }
/* Delete LSA from neighbor retransmit-list. */
ospf_ls_retransmit_delete_nbr_area (area, lsa);
+ /* Unregister LSA from refresh-list */
+ ospf_refresher_unregister_lsa (area->ospf, lsa);
+
/* Create new network-LSA instance. */
new = ospf_network_lsa_new (oi);
if (new == NULL)
- return -1;
- new->data->ls_seqnum = lsa_seqnum_increment (lsa);
-
- ospf_lsa_install (area->ospf, oi, new);
+ return NULL;
+
+ oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
+ assert (oip != NULL);
+ oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
+ new2 = ospf_lsa_install (area->ospf, oi, new);
+
+ assert (new2 == new);
+
/* Flood LSA through aera. */
ospf_flood_through_area (area, NULL, new);
@@ -1149,60 +1159,8 @@ ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
ospf_lsa_header_dump (new->data);
}
- return 0;
-}
-
-static int
-ospf_network_lsa_refresh_timer (struct thread *t)
-{
- struct ospf_interface *oi;
-
- oi = THREAD_ARG (t);
- oi->t_network_lsa_self = NULL;
-
- if (oi->network_lsa_self)
- /* Now refresh network-LSA. */
- ospf_network_lsa_refresh (oi->network_lsa_self, oi);
- else
- /* Newly create network-LSA. */
- ospf_network_lsa_originate (oi);
-
- return 0;
-}
-
-void
-ospf_network_lsa_timer_add (struct ospf_interface *oi)
-{
- /* Keep interface's self-originated network-LSA. */
- struct ospf_lsa *lsa = oi->network_lsa_self;
-
- /* Cancel previously schedules network-LSA timer. */
- if (oi->t_network_lsa_self)
- if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
- zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
- OSPF_TIMER_OFF (oi->t_network_lsa_self);
-
- /* If network-LSA is originated previously, check the interval time. */
- if (lsa)
- {
- int delay;
- if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
- {
- oi->t_network_lsa_self =
- thread_add_timer (master, ospf_network_lsa_refresh_timer,
- oi, delay);
- return;
- }
- }
-
- if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
- zlog_debug ("Scheduling network-LSA origination right away");
-
- /* Immediately refresh network-LSA. */
- oi->t_network_lsa_self =
- thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
+ return new;
}
-
static void
stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
@@ -1326,7 +1284,7 @@ ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
return new;
}
-struct ospf_lsa*
+static struct ospf_lsa*
ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
{
struct ospf_lsa *new;
@@ -1473,7 +1431,7 @@ ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
return new;
}
-struct ospf_lsa*
+static struct ospf_lsa*
ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
{
struct ospf_lsa *new;
@@ -2299,6 +2257,7 @@ ospf_external_lsa_refresh_default (struct ospf *ospf)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
+ ospf_refresher_unregister_lsa (ospf, lsa);
ospf_lsa_flush_as (ospf, lsa);
}
}
@@ -2327,7 +2286,7 @@ ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
}
/* Refresh AS-external-LSA. */
-void
+struct ospf_lsa *
ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
struct external_info *ei, int force)
{
@@ -2343,7 +2302,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
lsa->data->type, inet_ntoa (lsa->data->id));
ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ei->ifindex /*, ei->nexthop */);
- return;
+ return NULL;
}
if (!changed && !force)
@@ -2351,7 +2310,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
lsa->data->type, inet_ntoa (lsa->data->id));
- return;
+ return NULL;
}
/* Delete LSA from neighbor retransmit-list. */
@@ -2367,7 +2326,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
inet_ntoa (lsa->data->id));
- return;
+ return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment (lsa);
@@ -2396,7 +2355,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
ospf_lsa_header_dump (new->data);
}
- return;
+ return new;
}
@@ -2404,8 +2363,8 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
/* Install router-LSA to an area. */
static struct ospf_lsa *
-ospf_router_lsa_install (struct ospf *ospf,
- struct ospf_lsa *new, int rt_recalc)
+ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
+ int rt_recalc)
{
struct ospf_area *area = new->area;
@@ -2424,15 +2383,11 @@ ospf_router_lsa_install (struct ospf *ospf,
if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
return new; /* ignore stale LSA */
- /* Set router-LSA refresh timer. */
- OSPF_TIMER_OFF (area->t_router_lsa_self);
- OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
- ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
-
/* Set self-originated router-LSA. */
ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = ospf_lsa_lock (new);
+ ospf_refresher_register_lsa (ospf, new);
}
if (rt_recalc)
ospf_spf_calculate_schedule (ospf);
@@ -2465,15 +2420,9 @@ ospf_network_lsa_install (struct ospf *ospf,
if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
return new; /* ignore stale LSA */
- /* Set LSRefresh timer. */
- OSPF_TIMER_OFF (oi->t_network_lsa_self);
-
- OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
- ospf_network_lsa_refresh_timer,
- OSPF_LS_REFRESH_TIME);
-
ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = ospf_lsa_lock (new);
+ ospf_refresher_register_lsa (ospf, new);
}
if (rt_recalc)
ospf_spf_calculate_schedule (ospf);
@@ -2721,7 +2670,8 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
{
zlog_debug ("ospf_lsa_install() Premature Aging "
- "lsa 0x%lx", (u_long)lsa);
+ "lsa 0x%p, seqnum 0x%x",
+ lsa, ntohl(lsa->data->ls_seqnum));
ospf_lsa_header_dump (lsa->data);
}
}
@@ -2826,7 +2776,7 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
new->data->type,
inet_ntoa (new->data->id),
lsa);
- ospf_lsa_maxage (ospf, lsa);
+ ospf_lsa_flush (ospf, lsa);
}
return new;
@@ -2858,35 +2808,6 @@ ospf_check_nbr_status (struct ospf *ospf)
}
-#ifdef ORIGINAL_CODING
-/* This function flood the maxaged LSA to DR. */
-void
-ospf_maxage_flood (struct ospf_lsa *lsa)
-{
- switch (lsa->data->type)
- {
- case OSPF_ROUTER_LSA:
- case OSPF_NETWORK_LSA:
- case OSPF_SUMMARY_LSA:
- case OSPF_ASBR_SUMMARY_LSA:
- case OSPF_AS_NSSA_LSA:
-#ifdef HAVE_OPAQUE_LSA
- case OSPF_OPAQUE_LINK_LSA:
- case OSPF_OPAQUE_AREA_LSA:
-#endif /* HAVE_OPAQUE_LSA */
- ospf_flood_through_area (lsa->area, NULL, lsa);
- break;
- case OSPF_AS_EXTERNAL_LSA:
-#ifdef HAVE_OPAQUE_LSA
- case OSPF_OPAQUE_AS_LSA:
-#endif /* HAVE_OPAQUE_LSA */
- ospf_flood_through_as (NULL, lsa);
- break;
- default:
- break;
- }
-}
-#endif /* ORIGINAL_CODING */
static int
ospf_maxage_lsa_remover (struct thread *thread)
@@ -2911,7 +2832,11 @@ ospf_maxage_lsa_remover (struct thread *thread)
reschedule = 1;
continue;
}
-
+
+ /* TODO: maybe convert this function to a work-queue */
+ if (thread_should_yield (thread))
+ OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
+
/* Remove LSA from the LSDB */
if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
@@ -2922,19 +2847,11 @@ ospf_maxage_lsa_remover (struct thread *thread)
zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
lsa->data->type, inet_ntoa (lsa->data->id));
- /* Flood max age LSA. */
-#ifdef ORIGINAL_CODING
- ospf_maxage_flood (lsa);
-#else /* ORIGINAL_CODING */
- ospf_flood_through (ospf, NULL, lsa);
-#endif /* ORIGINAL_CODING */
-
- if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
+ if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
{
if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
- zlog_debug ("originating new router lsa for lsa 0x%lx \n",
- (u_long)lsa);
- ospf_router_lsa_originate(lsa->area);
+ zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
+ ospf_lsa_refresh (ospf, lsa);
}
/* Remove from lsdb. */
@@ -2953,7 +2870,8 @@ ospf_maxage_lsa_remover (struct thread *thread)
neighbor Link state retransmission lists and b) none of the router's
neighbors are in states Exchange or Loading. */
if (reschedule)
- OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
+ OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
+ ospf->maxage_delay);
return 0;
}
@@ -2971,6 +2889,11 @@ ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
}
}
+/* Add LSA onto the MaxAge list, and schedule for removal.
+ * This does *not* lead to the LSA being flooded, that must be taken
+ * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
+ * function).
+ */
void
ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
{
@@ -2990,7 +2913,8 @@ ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
- OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
+ OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
+ ospf->maxage_delay);
}
static int
@@ -3035,6 +2959,10 @@ ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
ospf_lsa_maxage (ospf, lsa);
}
+ if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
+ if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
+ printf ("Eek! Shouldn't happen!\n");
+
return 0;
}
@@ -3353,6 +3281,7 @@ ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
switch (lsa->data->type)
{
#ifdef HAVE_OPAQUE_LSA
+ /* Opaque wants to be notified of flushes */
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
case OSPF_OPAQUE_AS_LSA:
@@ -3360,7 +3289,8 @@ ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
break;
#endif /* HAVE_OPAQUE_LSA */
default:
- ospf_lsa_maxage (ospf, lsa);
+ ospf_refresher_unregister_lsa (ospf, lsa);
+ ospf_lsa_flush (ospf, lsa);
break;
}
@@ -3383,12 +3313,13 @@ ospf_flush_self_originated_lsas_now (struct ospf *ospf)
if ((lsa = area->router_lsa_self) != NULL)
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
-
+ zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
+ lsa->data->type, inet_ntoa (lsa->data->id));
+
+ ospf_refresher_unregister_lsa (ospf, lsa);
ospf_lsa_flush_area (lsa, area);
ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = NULL;
- OSPF_TIMER_OFF (area->t_router_lsa_self);
}
for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
@@ -3398,12 +3329,13 @@ ospf_flush_self_originated_lsas_now (struct ospf *ospf)
&& oi->full_nbrs > 0)
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
-
+ zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
+ lsa->data->type, inet_ntoa (lsa->data->id));
+
+ ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
ospf_lsa_flush_area (oi->network_lsa_self, area);
ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = NULL;
- OSPF_TIMER_OFF (oi->t_network_lsa_self);
}
if (oi->type != OSPF_IFTYPE_VIRTUALLINK
@@ -3603,23 +3535,28 @@ ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
/* LSA Refreshment functions. */
-static void
+struct ospf_lsa *
ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
{
struct external_info *ei;
+ struct ospf_lsa *new = NULL;
assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
+ assert (lsa->lock > 0);
switch (lsa->data->type)
{
/* Router and Network LSAs are processed differently. */
case OSPF_ROUTER_LSA:
+ new = ospf_router_lsa_refresh (lsa);
+ break;
case OSPF_NETWORK_LSA:
+ new = ospf_network_lsa_refresh (lsa);
break;
case OSPF_SUMMARY_LSA:
- ospf_summary_lsa_refresh (ospf, lsa);
+ new = ospf_summary_lsa_refresh (ospf, lsa);
break;
case OSPF_ASBR_SUMMARY_LSA:
- ospf_summary_asbr_lsa_refresh (ospf, lsa);
+ new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
break;
case OSPF_AS_EXTERNAL_LSA:
/* Translated from NSSA Type-5s are refreshed when
@@ -3629,7 +3566,7 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
break;
ei = ospf_external_info_check (lsa);
if (ei)
- ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
+ new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
else
ospf_lsa_flush_as (ospf, lsa);
break;
@@ -3637,12 +3574,13 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
case OSPF_OPAQUE_AS_LSA:
- ospf_opaque_lsa_refresh (lsa);
+ new = ospf_opaque_lsa_refresh (lsa);
break;
#endif /* HAVE_OPAQUE_LSA */
default:
break;
}
+ return new;
}
void
@@ -3650,6 +3588,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
{
u_int16_t index, current_index;
+ assert (lsa->lock > 0);
assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
if (lsa->refresh_list < 0)
@@ -3668,11 +3607,11 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
if (delay < 0)
delay = 0;
- current_index = ospf->lsa_refresh_queue.index +
- (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
+ current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
+ - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
- % (OSPF_LSA_REFRESHER_SLOTS);
+ % (OSPF_LSA_REFRESHER_SLOTS);
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
@@ -3692,6 +3631,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
void
ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
{
+ assert (lsa->lock > 0);
assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
if (lsa->refresh_list >= 0)
{
@@ -3728,8 +3668,9 @@ ospf_lsa_refresh_walker (struct thread *t)
modulus. */
ospf->lsa_refresh_queue.index =
((unsigned long)(ospf->lsa_refresh_queue.index +
- (quagga_time (NULL) - ospf->lsa_refresher_started) /
- OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
+ (quagga_time (NULL) - ospf->lsa_refresher_started)
+ / OSPF_LSA_REFRESHER_GRANULARITY))
+ % OSPF_LSA_REFRESHER_SLOTS;
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
@@ -3744,6 +3685,8 @@ ospf_lsa_refresh_walker (struct thread *t)
refresh_list = ospf->lsa_refresh_queue.qs [i];
+ assert (i >= 0);
+
ospf->lsa_refresh_queue.qs [i] = NULL;
if (refresh_list)
@@ -3755,8 +3698,8 @@ ospf_lsa_refresh_walker (struct thread *t)
"refresh lsa %p (slot %d)",
inet_ntoa (lsa->data->id), lsa, i);
+ assert (lsa->lock > 0);
list_delete_node (refresh_list, node);
- ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
lsa->refresh_list = -1;
listnode_add (lsa_to_refresh, lsa);
}
@@ -3769,7 +3712,11 @@ ospf_lsa_refresh_walker (struct thread *t)
ospf->lsa_refresher_started = quagga_time (NULL);
for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
- ospf_lsa_refresh (ospf, lsa);
+ {
+ ospf_lsa_refresh (ospf, lsa);
+ assert (lsa->lock > 0);
+ ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
+ }
list_delete (lsa_to_refresh);
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 251d4731..72e2f8a5 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -114,11 +114,9 @@ struct ospf_lsa
/* Refreshement List or Queue */
int refresh_list;
-
-#ifdef HAVE_OPAQUE_LSA
- /* For Type-9 Opaque-LSAs, reference to ospf-interface is required. */
+
+ /* For Type-9 Opaque-LSAs */
struct ospf_interface *oi;
-#endif /* HAVE_OPAQUE_LSA */
};
/* OSPF LSA Link Type. */
@@ -254,19 +252,16 @@ extern struct lsa_header *ospf_lsa_data_dup (struct lsa_header *);
extern void ospf_lsa_data_free (struct lsa_header *);
/* Prototype for various LSAs */
-extern int ospf_router_lsa_update_timer (struct thread *);
-extern void ospf_router_lsa_timer_add (struct ospf_area *);
+extern int ospf_router_lsa_update (struct ospf *);
+extern int ospf_router_lsa_update_area (struct ospf_area *);
-extern int ospf_network_lsa_refresh (struct ospf_lsa *, struct ospf_interface *);
-extern void ospf_network_lsa_timer_add (struct ospf_interface *);
+extern void ospf_network_lsa_update (struct ospf_interface *);
extern struct ospf_lsa *ospf_summary_lsa_originate (struct prefix_ipv4 *, u_int32_t,
struct ospf_area *);
extern struct ospf_lsa *ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *,
u_int32_t,
struct ospf_area *);
-extern struct ospf_lsa *ospf_summary_lsa_refresh (struct ospf *, struct ospf_lsa *);
-extern struct ospf_lsa *ospf_summary_asbr_lsa_refresh (struct ospf *, struct ospf_lsa *);
extern struct ospf_lsa *ospf_lsa_install (struct ospf *,
struct ospf_interface *, struct ospf_lsa *);
@@ -300,12 +295,15 @@ extern void ospf_lsa_maxage (struct ospf *, struct ospf_lsa *);
extern u_int32_t get_metric (u_char *);
extern int ospf_lsa_maxage_walker (struct thread *);
-
+extern struct ospf_lsa *ospf_lsa_refresh (struct ospf *, struct ospf_lsa *);
+
extern void ospf_external_lsa_refresh_default (struct ospf *);
extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, int);
-extern void ospf_external_lsa_refresh (struct ospf *, struct ospf_lsa *,
- struct external_info *, int);
+extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *,
+ struct ospf_lsa *,
+ struct external_info *,
+ int);
extern struct in_addr ospf_lsa_unique_id (struct ospf *, struct ospf_lsdb *, u_char,
struct prefix_ipv4 *);
extern void ospf_schedule_lsa_flood_area (struct ospf_area *, struct ospf_lsa *);
diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c
index c906f052..ea9a3528 100644
--- a/ospfd/ospf_lsdb.c
+++ b/ospfd/ospf_lsdb.c
@@ -120,7 +120,10 @@ ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
/* nothing to do? */
if (rn->info && rn->info == lsa)
- return;
+ {
+ route_unlock_node (rn);
+ return;
+ }
/* purge old entry? */
if (rn->info)
@@ -162,12 +165,13 @@ ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
return;
}
+ assert (lsa->data->type < OSPF_MAX_LSA);
table = lsdb->type[lsa->data->type].db;
lsdb_prefix_set (&lp, lsa);
- rn = route_node_lookup (table, (struct prefix *) &lp);
- if (rn && (rn->info == lsa))
+ if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
{
- ospf_lsdb_delete_entry (lsdb, rn);
+ if (rn->info == lsa)
+ ospf_lsdb_delete_entry (lsdb, rn);
route_unlock_node (rn); /* route_node_lookup */
}
}
@@ -274,7 +278,8 @@ ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,
rn = route_top (table);
else
{
- rn = route_node_get (table, (struct prefix *) &lp);
+ if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
+ return NULL;
rn = route_next (rn);
}
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index 89ff2038..1e2d44e6 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -61,7 +61,7 @@ ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
"on # of multicast group memberships has been exceeded?",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s [%u] join AllSPFRouters Multicast group.",
+ zlog_debug ("interface %s [%u] join AllSPFRouters Multicast group.",
inet_ntoa (p->u.prefix4), ifindex);
return ret;
@@ -81,8 +81,8 @@ ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p,
"ifindex %u, AllSPFRouters): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s [%u] leave AllSPFRouters Multicast group.",
- inet_ntoa (p->u.prefix4), ifindex);
+ zlog_debug ("interface %s [%u] leave AllSPFRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
@@ -103,8 +103,8 @@ ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int
"on # of multicast group memberships has been exceeded?",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s [%u] join AllDRouters Multicast group.",
- inet_ntoa (p->u.prefix4), ifindex);
+ zlog_debug ("interface %s [%u] join AllDRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
@@ -123,8 +123,8 @@ ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int
"ifindex %u, AllDRouters): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s [%u] leave AllDRouters Multicast group.",
- inet_ntoa (p->u.prefix4), ifindex);
+ zlog_debug ("interface %s [%u] leave AllDRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index 15fff349..cbc31716 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -162,7 +162,7 @@ nsm_should_adj (struct ospf_neighbor *nbr)
/* OSPF NSM functions. */
static int
-nsm_hello_received (struct ospf_neighbor *nbr)
+nsm_packet_received (struct ospf_neighbor *nbr)
{
/* Start or Restart Inactivity Timer. */
OSPF_NSM_TIMER_OFF (nbr->t_inactivity);
@@ -216,7 +216,7 @@ ospf_db_summary_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
case OSPF_OPAQUE_LINK_LSA:
/* Exclude type-9 LSAs that does not have the same "oi" with "nbr". */
- if (lsa->oi != nbr->oi)
+ if (nbr->oi && ospf_if_exists (lsa->oi) != nbr->oi)
return 0;
break;
case OSPF_OPAQUE_AREA_LSA:
@@ -408,7 +408,7 @@ struct {
{
/* DependUpon: dummy state. */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { NULL, NSM_DependUpon }, /* HelloReceived */
+ { NULL, NSM_DependUpon }, /* PacketReceived */
{ NULL, NSM_DependUpon }, /* Start */
{ NULL, NSM_DependUpon }, /* 2-WayReceived */
{ NULL, NSM_DependUpon }, /* NegotiationDone */
@@ -425,7 +425,7 @@ struct {
{
/* Deleted: dummy state. */
{ NULL, NSM_Deleted }, /* NoEvent */
- { NULL, NSM_Deleted }, /* HelloReceived */
+ { NULL, NSM_Deleted }, /* PacketReceived */
{ NULL, NSM_Deleted }, /* Start */
{ NULL, NSM_Deleted }, /* 2-WayReceived */
{ NULL, NSM_Deleted }, /* NegotiationDone */
@@ -442,7 +442,7 @@ struct {
{
/* Down: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_Init }, /* HelloReceived */
+ { nsm_packet_received, NSM_Init }, /* PacketReceived */
{ nsm_start, NSM_Attempt }, /* Start */
{ NULL, NSM_Down }, /* 2-WayReceived */
{ NULL, NSM_Down }, /* NegotiationDone */
@@ -459,7 +459,7 @@ struct {
{
/* Attempt: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_Init }, /* HelloReceived */
+ { nsm_packet_received, NSM_Init }, /* PacketReceived */
{ NULL, NSM_Attempt }, /* Start */
{ NULL, NSM_Attempt }, /* 2-WayReceived */
{ NULL, NSM_Attempt }, /* NegotiationDone */
@@ -476,7 +476,7 @@ struct {
{
/* Init: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_Init }, /* HelloReceived */
+ { nsm_packet_received, NSM_Init }, /* PacketReceived */
{ NULL, NSM_Init }, /* Start */
{ nsm_twoway_received, NSM_DependUpon }, /* 2-WayReceived */
{ NULL, NSM_Init }, /* NegotiationDone */
@@ -493,7 +493,7 @@ struct {
{
/* 2-Way: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_TwoWay }, /* HelloReceived */
+ { nsm_packet_received, NSM_TwoWay }, /* HelloReceived */
{ NULL, NSM_TwoWay }, /* Start */
{ NULL, NSM_TwoWay }, /* 2-WayReceived */
{ NULL, NSM_TwoWay }, /* NegotiationDone */
@@ -510,7 +510,7 @@ struct {
{
/* ExStart: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_ExStart }, /* HelloReceived */
+ { nsm_packet_received, NSM_ExStart }, /* PacaketReceived */
{ NULL, NSM_ExStart }, /* Start */
{ NULL, NSM_ExStart }, /* 2-WayReceived */
{ nsm_negotiation_done, NSM_Exchange }, /* NegotiationDone */
@@ -527,7 +527,7 @@ struct {
{
/* Exchange: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_Exchange }, /* HelloReceived */
+ { nsm_packet_received, NSM_Exchange }, /* PacketReceived */
{ NULL, NSM_Exchange }, /* Start */
{ NULL, NSM_Exchange }, /* 2-WayReceived */
{ NULL, NSM_Exchange }, /* NegotiationDone */
@@ -544,7 +544,7 @@ struct {
{
/* Loading: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_Loading }, /* HelloReceived */
+ { nsm_packet_received, NSM_Loading }, /* PacketReceived */
{ NULL, NSM_Loading }, /* Start */
{ NULL, NSM_Loading }, /* 2-WayReceived */
{ NULL, NSM_Loading }, /* NegotiationDone */
@@ -560,7 +560,7 @@ struct {
},
{ /* Full: */
{ NULL, NSM_DependUpon }, /* NoEvent */
- { nsm_hello_received, NSM_Full }, /* HelloReceived */
+ { nsm_packet_received, NSM_Full }, /* PacketReceived */
{ NULL, NSM_Full }, /* Start */
{ NULL, NSM_Full }, /* 2-WayReceived */
{ NULL, NSM_Full }, /* NegotiationDone */
@@ -579,7 +579,7 @@ struct {
static const char *ospf_nsm_event_str[] =
{
"NoEvent",
- "HelloReceived",
+ "PacketReceived",
"Start",
"2-WayReceived",
"NegotiationDone",
@@ -711,7 +711,7 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
LOOKUP(ospf_nsm_state_msg, old_state),
LOOKUP(ospf_nsm_state_msg, state));
- ospf_router_lsa_timer_add (oi->area);
+ ospf_router_lsa_update_area (oi->area);
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
{
@@ -719,7 +719,7 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
if (vl_area)
- ospf_router_lsa_timer_add (vl_area);
+ ospf_router_lsa_update_area (vl_area);
}
/* Originate network-LSA. */
@@ -730,10 +730,9 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
ospf_lsa_flush_area (oi->network_lsa_self, oi->area);
ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = NULL;
- OSPF_TIMER_OFF (oi->t_network_lsa_self);
}
else
- ospf_network_lsa_timer_add (oi);
+ ospf_network_lsa_update (oi);
}
}
diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h
index 1121dae6..4f2ae808 100644
--- a/ospfd/ospf_nsm.h
+++ b/ospfd/ospf_nsm.h
@@ -39,7 +39,7 @@
/* OSPF Neighbor State Machine Event. */
#define NSM_NoEvent 0
-#define NSM_HelloReceived 1
+#define NSM_PacketReceived 1 /* HelloReceived in the protocol */
#define NSM_Start 2
#define NSM_TwoWayReceived 3
#define NSM_NegotiationDone 4
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 0b6ac4cb..aa126e19 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -251,7 +251,7 @@ struct ospf_opaque_functab
void (* config_write_debug )(struct vty *vty);
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa);
int (* lsa_originator)(void *arg);
- void (* lsa_refresher )(struct ospf_lsa *lsa);
+ struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa);
int (* new_lsa_hook)(struct ospf_lsa *lsa);
int (* del_lsa_hook)(struct ospf_lsa *lsa);
};
@@ -354,7 +354,7 @@ ospf_register_opaque_functab (
void (* config_write_debug )(struct vty *vty),
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa),
int (* lsa_originator)(void *arg),
- void (* lsa_refresher )(struct ospf_lsa *lsa),
+ struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),
int (* new_lsa_hook)(struct ospf_lsa *lsa),
int (* del_lsa_hook)(struct ospf_lsa *lsa))
{
@@ -1608,12 +1608,13 @@ out:
return new;
}
-void
+struct ospf_lsa *
ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
{
struct ospf *ospf;
struct ospf_opaque_functab *functab;
-
+ struct ospf_lsa *new = NULL;
+
ospf = ospf_lookup ();
if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL
@@ -1630,12 +1631,12 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
- ospf_lsa_maxage (ospf, lsa);
+ ospf_lsa_flush (ospf, lsa);
}
else
- (* functab->lsa_refresher)(lsa);
+ new = (* functab->lsa_refresher)(lsa);
- return;
+ return new;
}
/*------------------------------------------------------------------------*
@@ -2108,7 +2109,7 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
/* This lsa will be flushed and removed eventually. */
- ospf_lsa_maxage (lsa0->area->ospf, lsa);
+ ospf_lsa_flush (lsa0->area->ospf, lsa);
out:
return;
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index f49fe460..22730645 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -120,7 +120,7 @@ ospf_register_opaque_functab (
void (* config_write_debug )(struct vty *vty),
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa),
int (* lsa_originator)(void *arg),
- void (* lsa_refresher )(struct ospf_lsa *lsa),
+ struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),
int (* new_lsa_hook)(struct ospf_lsa *lsa),
int (* del_lsa_hook)(struct ospf_lsa *lsa)
);
@@ -143,7 +143,7 @@ extern void ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi,
int *init_delay);
extern struct ospf_lsa *ospf_opaque_lsa_install (struct ospf_lsa *,
int rt_recalc);
-extern void ospf_opaque_lsa_refresh (struct ospf_lsa *lsa);
+extern struct ospf_lsa *ospf_opaque_lsa_refresh (struct ospf_lsa *lsa);
extern void ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,
u_char lsa_type,
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 1b68fd5a..be137d91 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -125,6 +125,20 @@ ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
fifo->count++;
}
+/* Add new packet to head of fifo. */
+static void
+ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
+{
+ op->next = fifo->head;
+
+ if (fifo->tail == NULL)
+ fifo->tail = op;
+
+ fifo->head = op;
+
+ fifo->count++;
+}
+
/* Delete first packet from fifo. */
struct ospf_packet *
ospf_fifo_pop (struct ospf_fifo *fifo)
@@ -199,6 +213,27 @@ ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
/* ospf_fifo_debug (oi->obuf); */
}
+static void
+ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
+{
+ if (!oi->obuf)
+ {
+ zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
+ "destination %s) called with NULL obuf, ignoring "
+ "(please report this bug)!\n",
+ IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
+ ospf_packet_type_str[stream_getc_from(op->s, 1)],
+ inet_ntoa (op->dst));
+ return;
+ }
+
+ /* Add packet to head of queue. */
+ ospf_fifo_push_head (oi->obuf, op);
+
+ /* Debug of packet fifo*/
+ /* ospf_fifo_debug (oi->obuf); */
+}
+
void
ospf_packet_delete (struct ospf_interface *oi)
{
@@ -888,7 +923,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
old_state = nbr->state;
/* Add event to thread. */
- OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
/* RFC2328 Section 9.5.1
If the router is not eligible to become Designated Router,
@@ -908,7 +943,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
if (oi->type == OSPF_IFTYPE_NBMA &&
(old_state == NSM_Down || old_state == NSM_Attempt))
{
- OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
nbr->priority = hello->priority;
nbr->d_router = hello->d_router;
nbr->bd_router = hello->bd_router;
@@ -918,12 +953,12 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
size - OSPF_HELLO_MIN_SIZE))
{
- OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
nbr->options |= hello->options;
}
else
{
- OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
/* Set neighbor information. */
nbr->priority = hello->priority;
nbr->d_router = hello->d_router;
@@ -1198,6 +1233,9 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
}
#endif /* HAVE_OPAQUE_LSA */
+ /* Add event to thread. */
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
/* Process DD packet by neighbor status. */
switch (nbr->state)
{
@@ -1419,6 +1457,9 @@ ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
return;
}
+ /* Add event to thread. */
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
/* Neighbor State should be Exchange or later. */
if (nbr->state != NSM_Exchange &&
nbr->state != NSM_Loading &&
@@ -1651,6 +1692,9 @@ ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
return;
}
+ /* Add event to thread. */
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
/* Check neighbor state. */
if (nbr->state < NSM_Exchange)
{
@@ -1953,7 +1997,7 @@ ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
if (tv_cmp (tv_sub (now, current->tv_orig),
- int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
+ int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
/* Trap NSSA type later.*/
ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
DISCARD_LSA (lsa, 8);
@@ -1984,6 +2028,9 @@ ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
return;
}
+ /* Add event to thread. */
+ OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
if (nbr->state < NSM_Exchange)
{
zlog_warn ("Link State Acknowledgment: "
@@ -2971,8 +3018,8 @@ ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
return length;
}
-void
-ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
+static void
+ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
{
struct ospf_packet *op;
u_int16_t length = OSPF_HEADER_SIZE;
@@ -2991,10 +3038,12 @@ ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
/* Set packet length. */
op->length = length;
- op->dst.s_addr = addr->s_addr;
+ op->dst.s_addr = addr;
- /* Add packet to the interface output queue. */
- ospf_packet_add (oi, op);
+ /* Add packet to the top of the interface output queue, so that they
+ * can't get delayed by things like long queues of LS Update packets
+ */
+ ospf_packet_add_top (oi, op);
/* Hook thread to write packet. */
OSPF_ISM_WRITE_ON (oi->ospf);
@@ -3025,7 +3074,7 @@ ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
&& oi->state != ISM_DR && oi->state != ISM_Backup)
return;
- ospf_hello_send_sub (oi, &nbr_nbma->addr);
+ ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
}
int
@@ -3064,7 +3113,7 @@ ospf_hello_reply_timer (struct thread *thread)
zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
- ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
+ ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
return 0;
}
@@ -3073,27 +3122,10 @@ ospf_hello_reply_timer (struct thread *thread)
void
ospf_hello_send (struct ospf_interface *oi)
{
- struct ospf_packet *op;
- u_int16_t length = OSPF_HEADER_SIZE;
-
/* If this is passive interface, do not send OSPF Hello. */
if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
return;
- op = ospf_packet_new (oi->ifp->mtu);
-
- /* Prepare OSPF common header. */
- ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
-
- /* Prepare OSPF Hello body. */
- length += ospf_make_hello (oi, op->s);
-
- /* Fill OSPF header. */
- ospf_fill_header (oi, op->s, length);
-
- /* Set packet length. */
- op->length = length;
-
if (oi->type == OSPF_IFTYPE_NBMA)
{
struct ospf_neighbor *nbr;
@@ -3123,34 +3155,16 @@ ospf_hello_send (struct ospf_interface *oi)
if (nbr->priority == 0 && oi->state == ISM_DROther)
continue;
/* if oi->state == Waiting, send hello to all neighbors */
- {
- struct ospf_packet *op_dup;
-
- op_dup = ospf_packet_dup(op);
- op_dup->dst = nbr->address.u.prefix4;
-
- /* Add packet to the interface output queue. */
- ospf_packet_add (oi, op_dup);
-
- OSPF_ISM_WRITE_ON (oi->ospf);
- }
-
+ ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
}
- ospf_packet_free (op);
}
else
{
/* Decide destination address. */
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
- op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
- else
- op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
-
- /* Add packet to the interface output queue. */
- ospf_packet_add (oi, op);
-
- /* Hook thread to write packet. */
- OSPF_ISM_WRITE_ON (oi->ospf);
+ ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
+ else
+ ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
}
}
diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
index 7b3d6866..9a472081 100644
--- a/ospfd/ospf_packet.h
+++ b/ospfd/ospf_packet.h
@@ -162,6 +162,5 @@ extern int ospf_ls_upd_timer (struct thread *);
extern int ospf_ls_ack_timer (struct thread *);
extern int ospf_poll_timer (struct thread *);
extern int ospf_hello_reply_timer (struct thread *);
-extern void ospf_hello_send_sub (struct ospf_interface *, struct in_addr *);
#endif /* _ZEBRA_OSPF_PACKET_H */
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index c5ec0ad8..24e81052 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -133,7 +133,7 @@ static void ospf_mpls_te_config_write_router (struct vty *vty);
static void ospf_mpls_te_config_write_if (struct vty *vty, struct interface *ifp);
static void ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa);
static int ospf_mpls_te_lsa_originate (void *arg);
-static void ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);
+static struct ospf_lsa *ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);
static void ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, enum sched_opcode);
static void del_mpls_te_link (void *val);
@@ -1009,7 +1009,7 @@ out:
return rc;
}
-static void
+static struct ospf_lsa *
ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)
{
struct mpls_te_link *lp;
@@ -1070,7 +1070,7 @@ ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)
}
out:
- return;
+ return new;
}
static void
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index adc822a7..46e7ffa5 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -2933,7 +2933,13 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf,
inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE);
}
}
-
+
+ /* Next network-LSA sequence number we'll use, if we're elected DR */
+ if (oi->params && ntohl (oi->params->network_lsa_seqnum)
+ != OSPF_INITIAL_SEQUENCE_NUMBER)
+ vty_out (vty, " Saved Network-LSA sequence number 0x%x%s",
+ ntohl (oi->params->network_lsa_seqnum), VTY_NEWLINE);
+
vty_out (vty, " Multicast group memberships:");
if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
|| OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
@@ -7023,7 +7029,7 @@ DEFUN (ospf_max_metric_router_lsa_admin,
SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
}
return CMD_SUCCESS;
}
@@ -7049,7 +7055,7 @@ DEFUN (no_ospf_max_metric_router_lsa_admin,
&& !area->t_stub_router)
{
UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
}
}
return CMD_SUCCESS;
@@ -7102,7 +7108,7 @@ DEFUN (no_ospf_max_metric_router_lsa_startup,
if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
{
UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
}
}
return CMD_SUCCESS;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index a7553e73..0188ffda 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -131,8 +131,8 @@ ospf_router_id_update (struct ospf *ospf)
ospf->external_origin = 0;
}
- OSPF_TIMER_ON (ospf->t_router_lsa_update,
- ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+ /* update router-lsa's for each area */
+ ospf_router_lsa_update (ospf);
/* update ospf_interface's */
for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
@@ -199,6 +199,7 @@ ospf_new (void)
new->spf_hold_multiplier = 1;
/* MaxAge init. */
+ new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
new->maxage_lsa = list_new ();
new->t_maxage_walker =
thread_add_timer (master, ospf_lsa_maxage_walker,
@@ -337,7 +338,7 @@ ospf_deferred_shutdown_check (struct ospf *ospf)
SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
}
timeout = ospf->stub_router_shutdown_time;
}
@@ -473,7 +474,6 @@ ospf_finish_final (struct ospf *ospf)
/* Cancel all timers. */
OSPF_TIMER_OFF (ospf->t_external_lsa);
- OSPF_TIMER_OFF (ospf->t_router_lsa_update);
OSPF_TIMER_OFF (ospf->t_spf_calc);
OSPF_TIMER_OFF (ospf->t_ase_calc);
OSPF_TIMER_OFF (ospf->t_maxage);
@@ -631,7 +631,6 @@ ospf_area_free (struct ospf_area *area)
free (IMPORT_NAME (area));
/* Cancel timer. */
- OSPF_TIMER_OFF (area->t_router_lsa_self);
OSPF_TIMER_OFF (area->t_stub_router);
#ifdef HAVE_OPAQUE_LSA
OSPF_TIMER_OFF (area->t_opaque_lsa_self);
@@ -1041,7 +1040,7 @@ ospf_area_type_set (struct ospf_area *area, int type)
break;
}
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
ospf_schedule_abr_task (area->ospf);
}
@@ -1052,7 +1051,7 @@ ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
return 0;
area->shortcut_configured = mode;
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
ospf_schedule_abr_task (ospf);
ospf_area_check_free (ospf, area->area_id);
@@ -1064,7 +1063,7 @@ int
ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
{
area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
- ospf_router_lsa_timer_add (area);
+ ospf_router_lsa_update_area (area);
ospf_area_check_free (ospf, area->area_id);
ospf_schedule_abr_task (ospf);
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index b24b3ced..0e57c452 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -58,6 +58,7 @@
#endif
#define OSPF_MIN_LS_INTERVAL 5
#define OSPF_MIN_LS_ARRIVAL 1
+#define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */
#define OSPF_LSA_MAXAGE 3600
#define OSPF_CHECK_AGE 300
#define OSPF_LSA_MAXAGE_DIFF 900
@@ -66,7 +67,6 @@
#define OSPF_INITIAL_SEQUENCE_NUMBER 0x80000001
#define OSPF_MAX_SEQUENCE_NUMBER 0x7fffffff
-#define OSPF_LSA_MAXAGE_CHECK_INTERVAL 30
#define OSPF_NSSA_TRANS_STABLE_DEFAULT 40
#define OSPF_ALLSPFROUTERS 0xe0000005 /* 224.0.0.5 */
@@ -251,7 +251,6 @@ struct ospf
int redistribute; /* Num of redistributed protocols. */
/* Threads. */
- struct thread *t_router_lsa_update; /* router-LSA update timer. */
struct thread *t_abr_task; /* ABR task timer. */
struct thread *t_asbr_check; /* ASBR check timer. */
struct thread *t_distribute_update; /* Distirbute list update timer. */
@@ -261,8 +260,13 @@ struct ospf
#ifdef HAVE_OPAQUE_LSA
struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
#endif /* HAVE_OPAQUE_LSA */
+
+#define OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT 60
+ unsigned int maxage_delay; /* Delay on Maxage remover timer, sec */
struct thread *t_maxage; /* MaxAge LSA remover timer. */
+#define OSPF_LSA_MAXAGE_CHECK_INTERVAL 30
struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */
+
struct thread *t_deferred_shutdown; /* deferred/stub-router shutdown timer*/
struct thread *t_write;
@@ -433,7 +437,6 @@ struct ospf_area
struct vertex *spf;
/* Threads. */
- struct thread *t_router_lsa_self;/* Self-originated router-LSA timer. */
struct thread *t_stub_router; /* Stub-router timer */
#ifdef HAVE_OPAQUE_LSA
struct thread *t_opaque_lsa_self; /* Type-10 Opaque-LSAs origin. */
diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c
index 64dc27c0..662e5843 100644
--- a/ripd/rip_debug.c
+++ b/ripd/rip_debug.c
@@ -44,19 +44,16 @@ DEFUN (show_debugging_rip,
{
if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV)
{
- vty_out (vty, " RIP packet%s debugging is on%s",
- IS_RIP_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, " RIP packet debugging is on%s",
VTY_NEWLINE);
}
else
{
if (IS_RIP_DEBUG_SEND)
- vty_out (vty, " RIP packet send%s debugging is on%s",
- IS_RIP_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, " RIP packet send debugging is on%s",
VTY_NEWLINE);
else
- vty_out (vty, " RIP packet receive%s debugging is on%s",
- IS_RIP_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, " RIP packet receive debugging is on%s",
VTY_NEWLINE);
}
}
@@ -105,11 +102,12 @@ DEFUN (debug_rip_packet_direct,
rip_debug_packet |= RIP_DEBUG_SEND;
if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
rip_debug_packet |= RIP_DEBUG_RECV;
- rip_debug_packet &= ~RIP_DEBUG_DETAIL;
return CMD_SUCCESS;
}
-DEFUN (debug_rip_packet_detail,
+/* N.B. the "detail" modifier is a no-op. we leave this command
+ for legacy compatibility. */
+DEFUN_DEPRECATED (debug_rip_packet_detail,
debug_rip_packet_detail_cmd,
"debug rip packet (recv|send) detail",
DEBUG_STR
@@ -124,7 +122,6 @@ DEFUN (debug_rip_packet_detail,
rip_debug_packet |= RIP_DEBUG_SEND;
if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
rip_debug_packet |= RIP_DEBUG_RECV;
- rip_debug_packet |= RIP_DEBUG_DETAIL;
return CMD_SUCCESS;
}
@@ -224,20 +221,17 @@ config_write_debug (struct vty *vty)
{
if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV)
{
- vty_out (vty, "debug rip packet%s%s",
- IS_RIP_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, "debug rip packet%s",
VTY_NEWLINE);
write++;
}
else
{
if (IS_RIP_DEBUG_SEND)
- vty_out (vty, "debug rip packet send%s%s",
- IS_RIP_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, "debug rip packet send%s",
VTY_NEWLINE);
else
- vty_out (vty, "debug rip packet recv%s%s",
- IS_RIP_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, "debug rip packet recv%s",
VTY_NEWLINE);
write++;
}
diff --git a/ripd/rip_debug.h b/ripd/rip_debug.h
index f3a07eea..990ec908 100644
--- a/ripd/rip_debug.h
+++ b/ripd/rip_debug.h
@@ -40,7 +40,6 @@
#define IS_RIP_DEBUG_PACKET (rip_debug_packet & RIP_DEBUG_PACKET)
#define IS_RIP_DEBUG_SEND (rip_debug_packet & RIP_DEBUG_SEND)
#define IS_RIP_DEBUG_RECV (rip_debug_packet & RIP_DEBUG_RECV)
-#define IS_RIP_DEBUG_DETAIL (rip_debug_packet & RIP_DEBUG_DETAIL)
#define IS_RIP_DEBUG_ZEBRA (rip_debug_zebra & RIP_DEBUG_ZEBRA)
diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c
index 78f13a71..33a7cf69 100644
--- a/ripngd/ripng_debug.c
+++ b/ripngd/ripng_debug.c
@@ -45,19 +45,16 @@ DEFUN (show_debugging_ripng,
{
if (IS_RIPNG_DEBUG_SEND && IS_RIPNG_DEBUG_RECV)
{
- vty_out (vty, " RIPng packet%s debugging is on%s",
- IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, " RIPng packet debugging is on%s",
VTY_NEWLINE);
}
else
{
if (IS_RIPNG_DEBUG_SEND)
- vty_out (vty, " RIPng packet send%s debugging is on%s",
- IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, " RIPng packet send debugging is on%s",
VTY_NEWLINE);
else
- vty_out (vty, " RIPng packet receive%s debugging is on%s",
- IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, " RIPng packet receive debugging is on%s",
VTY_NEWLINE);
}
}
@@ -106,11 +103,13 @@ DEFUN (debug_ripng_packet_direct,
ripng_debug_packet |= RIPNG_DEBUG_SEND;
if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
ripng_debug_packet |= RIPNG_DEBUG_RECV;
- ripng_debug_packet &= ~RIPNG_DEBUG_DETAIL;
+
return CMD_SUCCESS;
}
-DEFUN (debug_ripng_packet_detail,
+/* N.B. the "detail" modifier is a no-op. we leave this command
+ for legacy compatibility. */
+DEFUN_DEPRECATED (debug_ripng_packet_detail,
debug_ripng_packet_detail_cmd,
"debug ripng packet (recv|send) detail",
DEBUG_STR
@@ -125,7 +124,7 @@ DEFUN (debug_ripng_packet_detail,
ripng_debug_packet |= RIPNG_DEBUG_SEND;
if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
ripng_debug_packet |= RIPNG_DEBUG_RECV;
- ripng_debug_packet |= RIPNG_DEBUG_DETAIL;
+
return CMD_SUCCESS;
}
@@ -225,20 +224,17 @@ config_write_debug (struct vty *vty)
{
if (IS_RIPNG_DEBUG_SEND && IS_RIPNG_DEBUG_RECV)
{
- vty_out (vty, "debug ripng packet%s%s",
- IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, "debug ripng packet%s",
VTY_NEWLINE);
write++;
}
else
{
if (IS_RIPNG_DEBUG_SEND)
- vty_out (vty, "debug ripng packet send%s%s",
- IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, "debug ripng packet send%s",
VTY_NEWLINE);
else
- vty_out (vty, "debug ripng packet recv%s%s",
- IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+ vty_out (vty, "debug ripng packet recv%s",
VTY_NEWLINE);
write++;
}
diff --git a/ripngd/ripng_debug.h b/ripngd/ripng_debug.h
index f5ed6eab..674345c0 100644
--- a/ripngd/ripng_debug.h
+++ b/ripngd/ripng_debug.h
@@ -29,7 +29,6 @@
#define RIPNG_DEBUG_PACKET 0x01
#define RIPNG_DEBUG_SEND 0x20
#define RIPNG_DEBUG_RECV 0x40
-#define RIPNG_DEBUG_DETAIL 0x80
#define RIPNG_DEBUG_ZEBRA 0x01
@@ -39,7 +38,6 @@
#define IS_RIPNG_DEBUG_PACKET (ripng_debug_packet & RIPNG_DEBUG_PACKET)
#define IS_RIPNG_DEBUG_SEND (ripng_debug_packet & RIPNG_DEBUG_SEND)
#define IS_RIPNG_DEBUG_RECV (ripng_debug_packet & RIPNG_DEBUG_RECV)
-#define IS_RIPNG_DEBUG_DETAIL (ripng_debug_packet & RIPNG_DEBUG_DETAIL)
#define IS_RIPNG_DEBUG_ZEBRA (ripng_debug_zebra & RIPNG_DEBUG_ZEBRA)
diff --git a/tests/aspath_test.c b/tests/aspath_test.c
index fb504f31..9e51e8dd 100644
--- a/tests/aspath_test.c
+++ b/tests/aspath_test.c
@@ -649,7 +649,7 @@ make_aspath (const u_char *data, size_t len, int use32bit)
s = stream_new (len);
stream_put (s, data, len);
}
- as = aspath_parse (s, len, use32bit);
+ as = aspath_parse (s, len, use32bit, 0);
if (s)
stream_free (s);
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 808dcf74..b3111b8e 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -642,17 +642,14 @@ route_set_src (void *rule, struct prefix *prefix,
static void *
route_set_src_compile (const char *arg)
{
- sa_family_t family;
union g_addr src, *psrc;
- if (inet_pton(AF_INET, arg, &src.ipv4) > 0)
- family = AF_INET;
+ if (inet_pton(AF_INET, arg, &src.ipv4) != 1
#ifdef HAVE_IPV6
- else if (inet_pton(AF_INET6, arg, &src.ipv6) > 0)
- family = AF_INET6;
+ && inet_pton(AF_INET6, arg, &src.ipv6) != 1
#endif /* HAVE_IPV6 */
- else
- return NULL;
+ )
+ return NULL;
psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
*psrc = src;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index cb5e411c..dc3d432b 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -451,7 +451,7 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
}
/* Metric */
- if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
+ if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
{
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
stream_putc (s, rib->distance);