summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Grennan <tgrennan@vyatta.com>2008-04-10 21:56:49 +0000
committerTom Grennan <tgrennan@vyatta.com>2008-04-10 21:56:49 +0000
commitc1bdabf8dd2f22a33fdc35b70b93e871f179445d (patch)
tree570e66e842fc556fc643e97aa37e0183ded19f56
parentdb59fcc9e02b5755a92e4d2913420c1e09e05517 (diff)
parent9334b80b2c84f33d0d749b4a172f1d87a77a8544 (diff)
downloadquagga-c1bdabf8dd2f22a33fdc35b70b93e871f179445d.tar.bz2
quagga-c1bdabf8dd2f22a33fdc35b70b93e871f179445d.tar.xz
Merge branch 'upstream' into hollywood
Conflicts: ChangeLog zebra/zebra_rib.c
-rw-r--r--bgpd/ChangeLog30
-rw-r--r--bgpd/bgp_attr.c25
-rw-r--r--bgpd/bgp_attr.h2
-rw-r--r--bgpd/bgp_debug.c7
-rw-r--r--bgpd/bgp_network.c9
-rw-r--r--bgpd/bgp_open.c3
-rw-r--r--bgpd/bgp_packet.c13
-rwxr-xr-xconfigure.ac16
-rw-r--r--isisd/ChangeLog11
-rw-r--r--isisd/isis_flags.c19
-rw-r--r--isisd/isis_flags.h1
-rw-r--r--isisd/isisd.c8
-rw-r--r--lib/ChangeLog32
-rw-r--r--lib/linklist.c20
-rw-r--r--lib/log.c29
-rw-r--r--lib/log.h6
-rw-r--r--lib/memory.c2
-rw-r--r--lib/stream.h2
-rw-r--r--ospf6d/ospf6_area.h6
-rw-r--r--ospfd/ospf_opaque.h2
-rw-r--r--ospfd/ospfd.h6
-rw-r--r--ripd/ChangeLog6
-rw-r--r--ripd/rip_interface.c1
-rw-r--r--ripd/ripd.c1
-rw-r--r--solaris/ChangeLog6
-rw-r--r--solaris/Makefile.am2
-rw-r--r--tests/ChangeLog8
-rw-r--r--tests/aspath_test.c18
-rw-r--r--tests/bgp_capability_test.c30
-rw-r--r--zebra/ChangeLog28
-rw-r--r--zebra/ioctl.c26
-rw-r--r--zebra/kernel_socket.c22
-rw-r--r--zebra/rib.h1
-rw-r--r--zebra/zebra_rib.c56
34 files changed, 400 insertions, 54 deletions
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 3fa3837a..f3b6a8c1 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,3 +1,33 @@
+2008-03-13 Paul Jakma <paul.jakma@sun.com>
+
+ * (various) Remove 0 entries from struct message's, unneeded due to
+ recent improvements in mes_lookup/LOOKUP.
+
+2008-01-29 Jorge Boncompte <jorge@dti2.net>
+
+ * bgp_network.c: (bgp_socket) IPv4-only version crashes if -l is not
+ used as address will be null.
+
+2007-12-22 Paul Jakma <paul.jakma@sun.com>
+
+ * Fix series of vulnerabilities reported by "Mu Security
+ Research Team", where bgpd can be made to crash by sending
+ malformed packets - requires that bgpd be configured with a
+ session to the peer.
+ * bgp_attr.c: (bgp_attr_as4_path) aspath_parse may fail, only
+ set the attribute flag indicating AS4_PATH if we actually managed
+ to parse one.
+ (bgp_attr_munge_as4_attrs) Assert was too general, it is possible
+ to receive AS4_AGGREGATOR before AGGREGATOR.
+ (bgp_attr_parse) Check that we have actually received the extra
+ byte of header for Extended-Length attributes.
+ * bgp_attr.h: Fix BGP_ATTR_MIN_LEN to account for the length byte.
+ * bgp_open.c: (cap_minsizes) Fix size of CAPABILITY_CODE_RESTART,
+ incorrect -2 left in place from a development version of as4-path
+ patch.
+ * bgp_packet.c: (bgp_route_refresh_receive) ORF length parameter
+ needs to be properly sanity checked.
+
2007-12-18 Denis Ovsienko
* bgp_routemap.c: (no_set_aspath_prepend) This command cancelled
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index b463b3c0..26f62f5a 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -60,7 +60,6 @@ static struct message attr_str [] =
{ BGP_ATTR_AS4_PATH, "AS4_PATH" },
{ BGP_ATTR_AS4_AGGREGATOR, "AS4_AGGREGATOR" },
{ BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT" },
- { 0, NULL }
};
int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]);
@@ -892,7 +891,8 @@ bgp_attr_as4_path (struct peer *peer, bgp_size_t length,
*as4_path = aspath_parse (peer->ibuf, length, 1);
/* Set aspath attribute flag. */
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
+ if (as4_path)
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
return 0;
}
@@ -1126,10 +1126,10 @@ bgp_attr_munge_as4_attrs (struct peer *peer, struct attr *attr,
*/
if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR) ) )
{
- assert (attre);
-
if ( attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR) ) )
{
+ assert (attre);
+
/* received both.
* if the as_number in aggregator is not AS_TRANS,
* then AS4_AGGREGATOR and AS4_PATH shall be ignored
@@ -1170,7 +1170,7 @@ bgp_attr_munge_as4_attrs (struct peer *peer, struct attr *attr,
zlog_debug ("[AS4] %s BGP not AS4 capable peer send"
" AS4_AGGREGATOR but no AGGREGATOR, will take"
" it as if AGGREGATOR with AS_TRANS had been there", peer->host);
- attre->aggregator_as = as4_aggregator;
+ (attre = bgp_attr_extra_get (attr))->aggregator_as = as4_aggregator;
/* sweep it under the carpet and simulate a "good" AGGREGATOR */
attr->flag |= (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR));
}
@@ -1543,6 +1543,21 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
flag = stream_getc (BGP_INPUT (peer));
type = stream_getc (BGP_INPUT (peer));
+ /* Check whether Extended-Length applies and is in bounds */
+ if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN)
+ && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1)))
+ {
+ zlog (peer->log, LOG_WARNING,
+ "%s Extended length set, but just %u bytes of attr header",
+ peer->host,
+ (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
+
+ bgp_notify_send (peer,
+ BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
+ return -1;
+ }
+
/* Check extended attribue length bit. */
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN))
length = stream_getw (BGP_INPUT (peer));
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 1af9ce30..e152b9f4 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -44,7 +44,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define BGP_ATTR_FLAG_EXTLEN 0x10 /* Extended length flag. */
/* BGP attribute header must bigger than 2. */
-#define BGP_ATTR_MIN_LEN 2 /* Attribute flag and type. */
+#define BGP_ATTR_MIN_LEN 3 /* Attribute flag, type length. */
#define BGP_ATTR_DEFAULT_WEIGHT 32768
/* Additional/uncommon BGP attributes.
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index acb1de7f..757b9cf8 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -59,7 +59,6 @@ unsigned long term_bgp_debug_zebra;
/* messages for BGP-4 status */
struct message bgp_status_msg[] =
{
- { 0, "null" },
{ Idle, "Idle" },
{ Connect, "Connect" },
{ Active, "Active" },
@@ -86,7 +85,6 @@ const char *bgp_type_str[] =
/* message for BGP-4 Notify */
struct message bgp_notify_msg[] =
{
- { 0, "" },
{ BGP_NOTIFY_HEADER_ERR, "Message Header Error"},
{ BGP_NOTIFY_OPEN_ERR, "OPEN Message Error"},
{ BGP_NOTIFY_UPDATE_ERR, "UPDATE Message Error"},
@@ -99,7 +97,6 @@ int bgp_notify_msg_max = BGP_NOTIFY_MAX;
struct message bgp_notify_head_msg[] =
{
- { 0, "null"},
{ BGP_NOTIFY_HEADER_NOT_SYNC, "/Connection Not Synchronized"},
{ BGP_NOTIFY_HEADER_BAD_MESLEN, "/Bad Message Length"},
{ BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type"}
@@ -108,7 +105,6 @@ int bgp_notify_head_msg_max = BGP_NOTIFY_HEADER_MAX;
struct message bgp_notify_open_msg[] =
{
- { 0, "null" },
{ BGP_NOTIFY_OPEN_UNSUP_VERSION, "/Unsupported Version Number" },
{ BGP_NOTIFY_OPEN_BAD_PEER_AS, "/Bad Peer AS"},
{ BGP_NOTIFY_OPEN_BAD_BGP_IDENT, "/Bad BGP Identifier"},
@@ -121,7 +117,6 @@ int bgp_notify_open_msg_max = BGP_NOTIFY_OPEN_MAX;
struct message bgp_notify_update_msg[] =
{
- { 0, "null"},
{ BGP_NOTIFY_UPDATE_MAL_ATTR, "/Malformed Attribute List"},
{ BGP_NOTIFY_UPDATE_UNREC_ATTR, "/Unrecognized Well-known Attribute"},
{ BGP_NOTIFY_UPDATE_MISS_ATTR, "/Missing Well-known Attribute"},
@@ -138,7 +133,6 @@ int bgp_notify_update_msg_max = BGP_NOTIFY_UPDATE_MAX;
struct message bgp_notify_cease_msg[] =
{
- { 0, ""},
{ BGP_NOTIFY_CEASE_MAX_PREFIX, "/Maximum Number of Prefixes Reached"},
{ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, "/Administratively Shutdown"},
{ BGP_NOTIFY_CEASE_PEER_UNCONFIG, "/Peer Unconfigured"},
@@ -152,7 +146,6 @@ int bgp_notify_cease_msg_max = BGP_NOTIFY_CEASE_MAX;
struct message bgp_notify_capability_msg[] =
{
- { 0, "null" },
{ BGP_NOTIFY_CAPABILITY_INVALID_ACTION, "/Invalid Action Value" },
{ BGP_NOTIFY_CAPABILITY_INVALID_LENGTH, "/Invalid Capability Length"},
{ BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value"},
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 6b8c8a44..8452545d 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -296,7 +296,7 @@ bgp_socket (struct bgp *bgp, unsigned short port, char *address)
req.ai_flags = AI_PASSIVE;
req.ai_family = AF_UNSPEC;
req.ai_socktype = SOCK_STREAM;
- sprintf (port_str, "%d", port);
+ snprintf (port_str, sizeof(port_str), "%d", port);
port_str[sizeof (port_str) - 1] = '\0';
ret = getaddrinfo (address, port_str, &req, &ainfo);
@@ -380,11 +380,10 @@ bgp_socket (struct bgp *bgp, unsigned short port, char *address)
sin.sin_port = htons (port);
socklen = sizeof (struct sockaddr_in);
- ret = inet_aton(address, &sin.sin_addr);
-
- if (ret < 1)
+ if (address && ((ret = inet_aton(address, &sin.sin_addr)) < 1))
{
- zlog_err("bgp_socket: could not parse ip address %s: ", address, safe_strerror (errno));
+ zlog_err("bgp_socket: could not parse ip address %s: %s",
+ address, safe_strerror (errno));
return ret;
}
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 38431d4c..84d8191e 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -443,7 +443,6 @@ bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
static struct message capcode_str[] =
{
- { 0, ""},
{ CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
{ CAPABILITY_CODE_REFRESH, "Route Refresh" },
{ CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
@@ -461,7 +460,7 @@ static size_t cap_minsizes[] =
[CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
[CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
[CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
- [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr) - 2,
+ [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
[CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
[CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
[CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 2b56259b..e8f77f10 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1960,11 +1960,14 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
when_to_refresh = stream_getc (s);
end = stream_pnt (s) + (size - 5);
- while (stream_pnt (s) < end)
+ while ((stream_pnt (s) + 2) < end)
{
orf_type = stream_getc (s);
orf_len = stream_getw (s);
-
+
+ /* orf_len in bounds? */
+ if ((stream_pnt (s) + orf_len) > end)
+ break; /* XXX: Notify instead?? */
if (orf_type == ORF_TYPE_PREFIX
|| orf_type == ORF_TYPE_PREFIX_OLD)
{
@@ -1984,6 +1987,12 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
peer->host, orf_type, orf_len);
}
+ /* we're going to read at least 1 byte of common ORF header,
+ * and 7 bytes of ORF Address-filter entry from the stream
+ */
+ if (orf_len < 7)
+ break;
+
/* ORF prefix-list name */
sprintf (name, "%s.%d.%d", peer->host, afi, safi);
diff --git a/configure.ac b/configure.ac
index 857b6db4..bce20242 100755
--- a/configure.ac
+++ b/configure.ac
@@ -897,6 +897,22 @@ AC_TRY_COMPILE([#ifdef HAVE_SYS_PARAM_H
AC_DEFINE(HAVE_BSD_STRUCT_IP_MREQ_HACK,,[Can pass ifindex in struct ip_mreq])],
AC_MSG_RESULT(no))
+dnl ---------------------------------------------------------------
+dnl figure out how to check link-state
+dnl ---------------------------------------------------------------
+AC_CHECK_HEADER([net/if.h],
+ [AC_CHECK_HEADER( [net/if_media.h],
+ [m4_define([LINK_DETECT_INCLUDES],
+ QUAGGA_INCLUDES
+ [#include <net/if_media.h>
+ ])
+ AC_CHECK_MEMBERS( [struct ifmediareq.ifm_status],
+ AC_DEFINE(HAVE_BSD_LINK_DETECT,,[BSD link-detect]),
+ [], LINK_DETECT_INCLUDES)],
+ [],
+ QUAGGA_INCLUDES)],
+ [], QUAGGA_INCLUDES )
+
dnl -----------------------
dnl check proc file system.
dnl -----------------------
diff --git a/isisd/ChangeLog b/isisd/ChangeLog
index c2482f06..bb77ffea 100644
--- a/isisd/ChangeLog
+++ b/isisd/ChangeLog
@@ -1,3 +1,14 @@
+2008-01-29 James Carlson <james.d.carlson@sun.com>
+
+ * Fix bug #437, assert due to bogus index management
+ * isis_flags.c: (flags_initialize) new
+ * (flags_get_index) fix off by one, leading to list assert
+ on null node data.
+ (flags_free_index) ditto.
+ * isisd.c: (isis_area_create) use flags_initialize
+ (isis_area_destroy) deconfigure circuits when
+ taking down area.
+
2007-07-18 James Carlson <james.d.carlson@sun.com>
* isis_network.c: split up into isis_bpf.c, isis_dlpi.c, and
diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c
index 9c861c94..03c91101 100644
--- a/isisd/isis_flags.c
+++ b/isisd/isis_flags.c
@@ -29,6 +29,13 @@
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
+void
+flags_initialize (struct flags *flags)
+{
+ flags->maxindex = 0;
+ flags->free_idcs = NULL;
+}
+
int
flags_get_index (struct flags *flags)
{
@@ -37,14 +44,14 @@ flags_get_index (struct flags *flags)
if (flags->free_idcs == NULL || flags->free_idcs->count == 0)
{
- flags->maxindex++;
- index = flags->maxindex;
+ index = flags->maxindex++;
}
else
{
node = listhead (flags->free_idcs);
index = (int) listgetdata (node);
listnode_delete (flags->free_idcs, (void *) index);
+ index--;
}
return index;
@@ -53,12 +60,18 @@ flags_get_index (struct flags *flags)
void
flags_free_index (struct flags *flags, int index)
{
+ if (index + 1 == flags->maxindex)
+ {
+ flags->maxindex--;
+ return;
+ }
+
if (flags->free_idcs == NULL)
{
flags->free_idcs = list_new ();
}
- listnode_add (flags->free_idcs, (void *) index);
+ listnode_add (flags->free_idcs, (void *) (index + 1));
return;
}
diff --git a/isisd/isis_flags.h b/isisd/isis_flags.h
index f2421f2f..13dd9e14 100644
--- a/isisd/isis_flags.h
+++ b/isisd/isis_flags.h
@@ -28,6 +28,7 @@
* the support will be achived using the newest drafts */
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in lsp.h as well */
+void flags_initialize (struct flags *flags);
struct flags *new_flags (int size);
int flags_get_index (struct flags *flags);
void flags_free_index (struct flags *flags, int index);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 48ea47af..7c669fcb 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -130,7 +130,7 @@ isis_area_create ()
area->circuit_list = list_new ();
area->area_addrs = list_new ();
THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
- area->flags.maxindex = -1;
+ flags_initialize (&area->flags);
/*
* Default values
*/
@@ -215,7 +215,11 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
if (area->circuit_list)
{
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
- isis_circuit_del (circuit);
+ {
+ /* The fact that it's in circuit_list means that it was configured */
+ isis_circuit_deconfigure (circuit, area);
+ isis_circuit_del (circuit);
+ }
list_delete (area->circuit_list);
}
diff --git a/lib/ChangeLog b/lib/ChangeLog
index bd66f071..da0fa8ca 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,35 @@
+2008-02-28 Paul Jakma <paul.jakma@sun.com>
+
+ * log.c: (mes_lookup) Sowmini Varadhan diagnosed a problem where
+ this function can cause a NULL dereference, on lookups for unknown
+ indices, or messages with NULL strings. Can occur, e.g., debug
+ logging code when processing received messages. Fixed to accept a
+ pointer to a default string to be used if there is no match.
+ * log.h: LOOKUP adjusted to match
+
+2008-02-28 Paul Jakma <paul.jakma@sun.com>
+
+ * linklist.c: This implementation expects that the data pointer not
+ be null, e.g. listgetdata() asserts this. The list add methods
+ don't apply the same sanity check.
+
+ Noted by Jim Carlson in bug #437.
+
+2008-01-11 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+ * zebra.h: Revert previous change, no need to include <net/if_media.h>
+ here.
+
+2008-01-10 Ingo Flaschberger <if@xip.at>
+
+ * zebra.h: If HAVE_BSD_LINK_DETECT is defined, include <net/if_media.h>.
+
+2008-01-08 Pavol Rusnak <prusnak@suse.cz>
+
+ * memory.c: (mtype_memstr) Fix accidental shift past width of type,
+ constant should have been forced to UL, rather than being left to
+ default to int.
+
2007-11-12 Denis Ovsienko
* linklist.c: (listnode_add_after) Don't forget to increment list
diff --git a/lib/linklist.c b/lib/linklist.c
index 983da2d1..a16e9e18 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -65,7 +65,9 @@ void
listnode_add (struct list *list, void *val)
{
struct listnode *node;
-
+
+ assert (val != NULL);
+
node = listnode_new ();
node->prev = list->tail;
@@ -91,7 +93,9 @@ listnode_add_sort (struct list *list, void *val)
{
struct listnode *n;
struct listnode *new;
-
+
+ assert (val != NULL);
+
new = listnode_new ();
new->data = val;
@@ -130,7 +134,9 @@ void
listnode_add_after (struct list *list, struct listnode *pp, void *val)
{
struct listnode *nn;
-
+
+ assert (val != NULL);
+
nn = listnode_new ();
nn->data = val;
@@ -266,7 +272,9 @@ void
list_add_node_prev (struct list *list, struct listnode *current, void *val)
{
struct listnode *node;
-
+
+ assert (val != NULL);
+
node = listnode_new ();
node->next = current;
node->data = val;
@@ -287,7 +295,9 @@ void
list_add_node_next (struct list *list, struct listnode *current, void *val)
{
struct listnode *node;
-
+
+ assert (val != NULL);
+
node = listnode_new ();
node->prev = current;
node->data = val;
diff --git a/lib/log.c b/lib/log.c
index ff47cae0..ce00bfbb 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -752,14 +752,24 @@ lookup (struct message *mes, int key)
}
/* Older/faster version of message lookup function, but requires caller to pass
- in the array size (instead of relying on a 0 key to terminate the search). */
+ * in the array size (instead of relying on a 0 key to terminate the search).
+ *
+ * The return value is the message string if found, or the 'none' pointer
+ * provided otherwise.
+ */
const char *
-mes_lookup (struct message *meslist, int max, int index)
+mes_lookup (struct message *meslist, int max, int index, const char *none)
{
+ int pos = index - meslist[0].key;
+
/* first check for best case: index is in range and matches the key
- value in that slot */
- if ((index >= 0) && (index < max) && (meslist[index].key == index))
- return meslist[index].str;
+ * value in that slot.
+ * NB: key numbering might be offset from 0. E.g. protocol constants
+ * often start at 1.
+ */
+ if ((pos >= 0) && (pos < max)
+ && (meslist[pos].key == index))
+ return meslist[pos].str;
/* fall back to linear search */
{
@@ -769,14 +779,17 @@ mes_lookup (struct message *meslist, int max, int index)
{
if (meslist->key == index)
{
+ const char *str = (meslist->str ? meslist->str : none);
+
zlog_debug ("message index %d [%s] found in position %d (max is %d)",
- index, meslist->str, i, max);
- return meslist->str;
+ index, str, i, max);
+ return str;
}
}
}
zlog_err("message index %d not found (max is %d)", index, max);
- return NULL;
+ assert (none);
+ return none;
}
/* Wrapper around strerror to handle case where it returns NULL. */
diff --git a/lib/log.h b/lib/log.h
index da8fbea8..7432b25e 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -142,10 +142,12 @@ extern int zlog_reset_file (struct zlog *zl);
extern int zlog_rotate (struct zlog *);
/* For hackey massage lookup and check */
-#define LOOKUP(x, y) mes_lookup(x, x ## _max, y)
+#define LOOKUP(x, y) mes_lookup(x, x ## _max, y, "(no item found)")
extern const char *lookup (struct message *, int);
-extern const char *mes_lookup (struct message *meslist, int max, int index);
+extern const char *mes_lookup (struct message *meslist,
+ int max, int index,
+ const char *no_item);
extern const char *zlog_priority[];
extern const char *zlog_proto_names[];
diff --git a/lib/memory.c b/lib/memory.c
index eb670722..9ed5e100 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -501,7 +501,7 @@ mtype_memstr (char *buf, size_t len, unsigned long bytes)
* Just hacked to make it not warn on 'smaller' machines.
* Static compiler analysis should mean no extra code
*/
- if (bytes & (1 << (sizeof (unsigned long) >= 8 ? 39 : 0)))
+ if (bytes & (1UL << (sizeof (unsigned long) >= 8 ? 39 : 0)))
t++;
snprintf (buf, len, "%4d TiB", t);
}
diff --git a/lib/stream.h b/lib/stream.h
index d2d2e401..715a083d 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -137,7 +137,7 @@ struct stream_fifo
*/
extern struct stream *stream_new (size_t);
extern void stream_free (struct stream *);
-extern struct stream * stream_copy (struct stream *new, struct stream *src);
+extern struct stream * stream_copy (struct stream *, struct stream *src);
extern struct stream *stream_dup (struct stream *);
extern size_t stream_resize (struct stream *, size_t);
extern size_t stream_get_getp (struct stream *);
diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h
index dd33ac47..6bf7e0b5 100644
--- a/ospf6d/ospf6_area.h
+++ b/ospf6d/ospf6_area.h
@@ -67,9 +67,9 @@ struct ospf6_area
{
char *name;
struct access_list *list;
- } export;
-#define EXPORT_NAME(A) (A)->export.name
-#define EXPORT_LIST(A) (A)->export.list
+ } _export;
+#define EXPORT_NAME(A) (A)->_export.name
+#define EXPORT_LIST(A) (A)->_export.list
/* Area acceptance list */
struct
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index fc8d6ff6..f49fe460 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -141,7 +141,7 @@ extern void ospf_opaque_lsa_dump (struct stream *s, u_int16_t length);
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 *new,
+extern struct ospf_lsa *ospf_opaque_lsa_install (struct ospf_lsa *,
int rt_recalc);
extern void ospf_opaque_lsa_refresh (struct ospf_lsa *lsa);
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 7a0ffcef..b6187111 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -397,9 +397,9 @@ struct ospf_area
{
char *name;
struct access_list *list;
- } export;
-#define EXPORT_NAME(A) (A)->export.name
-#define EXPORT_LIST(A) (A)->export.list
+ } _export;
+#define EXPORT_NAME(A) (A)->_export.name
+#define EXPORT_LIST(A) (A)->_export.list
/* Area acceptance list. */
struct
diff --git a/ripd/ChangeLog b/ripd/ChangeLog
index cb24e269..ecf353d0 100644
--- a/ripd/ChangeLog
+++ b/ripd/ChangeLog
@@ -1,3 +1,9 @@
+2008-03-13 Paul Jakma <paul.jakma@sun.com>
+
+ * ripd.c/rip_interface.c: Remove 0 entries from rip_msg
+ ri_version_msg struct message's, not needed with recent fixes
+ to mes_lookup.
+
2007-04-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* ripd.c: (rip_vty_out_uptime) Remove unused variable timer_now.
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index c8a1a84f..b6d9240f 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -55,7 +55,6 @@ struct message ri_version_msg[] =
{RI_RIP_VERSION_1, "1"},
{RI_RIP_VERSION_2, "2"},
{RI_RIP_VERSION_1_AND_2, "1 2"},
- {0, NULL}
};
extern struct zebra_privs_t ripd_privs;
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 75ac2159..c5e42705 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -84,7 +84,6 @@ struct message rip_msg[] =
{RIP_TRACEOFF, "TRACEOFF"},
{RIP_POLL, "POLL"},
{RIP_POLL_ENTRY, "POLL ENTRY"},
- {0, NULL}
};
/* Utility function to set boradcast option to the socket. */
diff --git a/solaris/ChangeLog b/solaris/ChangeLog
index c6d8b81d..8a2ad7d3 100644
--- a/solaris/ChangeLog
+++ b/solaris/ChangeLog
@@ -1,3 +1,9 @@
+2008-01-13 Paul Jakma <paul.jakma@sun.com>
+
+ * Makefile.am: pkg target should depend on the 'depend.%' files.
+ Crops up now that solaris/ doesn't get descended into by
+ general Quagga build.
+
2007-02-22 Paul Jakma <paul.jakma@sun.com>
* quagga.{xml,init}.in: Add licence boilerplate to ensure
diff --git a/solaris/Makefile.am b/solaris/Makefile.am
index 8cfd1418..674f4ebf 100644
--- a/solaris/Makefile.am
+++ b/solaris/Makefile.am
@@ -97,7 +97,7 @@ quagga.init: $(srcdir)/quagga.init.in Makefile
# construct the pkg
@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg: prototype.% \
- quagga.init pkginfo.%.full
+ depend.% quagga.init pkginfo.%.full
($(pkg_make) && \
$(pkg_trans) "QUAGGA$*")
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 94f58749..098afb55 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,11 @@
+2008-02-23 Paul Jakma <paul.jakma@sun.com>
+
+ * aspath_test.c: Test for 0-ASN sequences that still have data.
+
+2007-12-22 Paul Jakma <paul.jakma@sun.com>
+
+ * bgp_capability_test.c: Test for empty capabilities.
+
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test dupe-weeding from sets.
diff --git a/tests/aspath_test.c b/tests/aspath_test.c
index c12d07a5..fb504f31 100644
--- a/tests/aspath_test.c
+++ b/tests/aspath_test.c
@@ -402,6 +402,24 @@ static struct test_segment {
"8466 3 52737 4096 3456 {7099,8153}",
6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
},
+ { /* 25 */
+ "zero-size overflow",
+ "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
+ { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
+ 12,
+ { "", "",
+ 0, 0, 0, 0, 0, 0 },
+ },
+ { /* 26 */
+ "zero-size overflow + valid segment",
+ "seq(#AS=0:8466 3 52737),seq(4096 3456)",
+ { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01,
+ 0x2,0x2, 0x10,0x00, 0x0d,0x80 },
+ 14
+ ,
+ { "", "",
+ 0, 0, 0, 0, 0, 0 },
+ },
{ NULL, NULL, {0}, 0, { NULL, 0, 0 } }
};
diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c
index 6771b579..0dbf4fb9 100644
--- a/tests/bgp_capability_test.c
+++ b/tests/bgp_capability_test.c
@@ -362,6 +362,36 @@ static struct test_segment misc_segments[] =
},
15, SHOULD_ERR,
},
+ { "GR-empty",
+ "GR capability, but empty.",
+ { /* hdr */ 0x40, 0x0,
+ },
+ 2, SHOULD_ERR,
+ },
+ { "MP-empty",
+ "MP capability, but empty.",
+ { /* hdr */ 0x1, 0x0,
+ },
+ 2, SHOULD_ERR,
+ },
+ { "ORF-empty",
+ "ORF capability, but empty.",
+ { /* hdr */ 0x3, 0x0,
+ },
+ 2, SHOULD_ERR,
+ },
+ { "AS4-empty",
+ "AS4 capability, but empty.",
+ { /* hdr */ 0x41, 0x0,
+ },
+ 2, SHOULD_ERR,
+ },
+ { "dyn-empty",
+ "Dynamic capability, but empty.",
+ { /* hdr */ 0x42, 0x0,
+ },
+ 2, SHOULD_PARSE,
+ },
{ "dyn-old",
"Dynamic capability (deprecated version)",
{ CAPABILITY_CODE_DYNAMIC, 0x0 },
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index 3ce7b9ea..d9cae283 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -1,3 +1,31 @@
+2008-02-26 Denis Ovsienko
+ * zebra_rib.[ch]: (rib_lookup_and_pushup) New function, which makes sure,
+ that if_set_prefix() has nothing in its way of assigning an address.
+ * ioctl.c: (if_set_prefix) Use rib_lookup_and_pushup() to resolve
+ bug #326.
+
+2008-01-11 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+ * ioctl.c: If HAVE_BSD_LINK_DETECT is defined, include <net/if_media.h>
+ (if_get_flags) Remove debug messages about BSD link state.
+ * kernel_socket.c: (bsd_linkdetect_translate) If link state
+ is unknown, we should set the IFF_RUNNING flag.
+
+2008-01-10 Ingo Flaschberger <if@xip.at>
+
+ * ioctl.c: (if_get_flags) If HAVE_BSD_LINK_DETECT, use the SIOCGIFMEDIA
+ ioctl to ascertain link state.
+ * kernel_socket.c: (bsd_linkdetect_translate) New function to
+ map the ifm_data.ifi_link_state value into the IFF_RUNNING flag.
+ (ifm_read) Call bsd_linkdetect_translate to fix the IFF_RUNNING
+ flag before calling if_flags_update.
+
+2008-01-08 Michael Larson <mike@vyatta.com>
+
+ * zebra_rib.c: (nexthop_active_check) Replace if_is_up with
+ if_is_operative to solve problems with static interface
+ routes not behaving properly with link-detect.
+
2007-11-12 Denis Ovsienko
* connected.c: (connected_up_ipv4, connected_down_ipv4,
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index c9ec8d57..d536771a 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -33,6 +33,10 @@
#include "zebra/rt.h"
#include "zebra/interface.h"
+#ifdef HAVE_BSD_LINK_DETECT
+#include <net/if_media.h>
+#endif /* HAVE_BSD_LINK_DETECT*/
+
extern struct zebra_privs_t zserv_privs;
/* clear and set interface name string */
@@ -192,6 +196,7 @@ if_set_prefix (struct interface *ifp, struct connected *ifc)
struct prefix_ipv4 *p;
p = (struct prefix_ipv4 *) ifc->address;
+ rib_lookup_and_pushup (p);
memset (&addreq, 0, sizeof addreq);
strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
@@ -344,6 +349,9 @@ if_get_flags (struct interface *ifp)
{
int ret;
struct ifreq ifreq;
+#ifdef HAVE_BSD_LINK_DETECT
+ struct ifmediareq ifmr;
+#endif /* HAVE_BSD_LINK_DETECT */
ifreq_set_name (&ifreq, ifp);
@@ -353,6 +361,24 @@ if_get_flags (struct interface *ifp)
zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno));
return;
}
+#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */
+ (void) memset(&ifmr, 0, sizeof(ifmr));
+ strncpy (&ifmr.ifm_name, ifp->name, IFNAMSIZ);
+ if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
+ {
+ zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno));
+ return;
+ }
+ if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
+ {
+ if (ifmr.ifm_status & IFM_ACTIVE)
+ SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ else
+ UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ }
+ else /* Force always up */
+ SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+#endif /* HAVE_BSD_LINK_DETECT */
if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff));
}
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index a91d76f5..2e04b031 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -295,6 +295,19 @@ ifan_read (struct if_announcemsghdr *ifan)
}
#endif /* RTM_IFANNOUNCE */
+#ifdef HAVE_BSD_LINK_DETECT
+/* BSD link detect translation */
+static void
+bsd_linkdetect_translate (struct if_msghdr *ifm)
+{
+ if ((ifm->ifm_data.ifi_link_state >= LINK_STATE_UP) ||
+ (ifm->ifm_data.ifi_link_state == LINK_STATE_UNKNOWN))
+ SET_FLAG(ifm->ifm_flags, IFF_RUNNING);
+ else
+ UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING);
+}
+#endif /* HAVE_BSD_LINK_DETECT */
+
/*
* Handle struct if_msghdr obtained from reading routing socket or
* sysctl (from interface_list). There may or may not be sockaddrs
@@ -426,6 +439,11 @@ ifm_read (struct if_msghdr *ifm)
* structure with ifindex IFINDEX_INTERNAL.
*/
ifp->ifindex = ifm->ifm_index;
+
+#ifdef HAVE_BSD_LINK_DETECT /* translate BSD kernel msg for link-state */
+ bsd_linkdetect_translate(ifm);
+#endif /* HAVE_BSD_LINK_DETECT */
+
if_flags_update (ifp, ifm->ifm_flags);
#if defined(__bsdi__)
if_kvm_get_mtu (ifp);
@@ -453,6 +471,10 @@ ifm_read (struct if_msghdr *ifm)
return -1;
}
+#ifdef HAVE_BSD_LINK_DETECT /* translate BSD kernel msg for link-state */
+ bsd_linkdetect_translate(ifm);
+#endif /* HAVE_BSD_LINK_DETECT */
+
/* update flags and handle operative->inoperative transition, if any */
if_flags_update (ifp, ifm->ifm_flags);
diff --git a/zebra/rib.h b/zebra/rib.h
index 796a30eb..9621f2c8 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -212,6 +212,7 @@ extern struct nexthop *nexthop_blackhole_add (struct rib *);
extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
struct in_addr *);
extern void rib_lookup_and_dump (struct prefix_ipv4 *);
+extern void rib_lookup_and_pushup (struct prefix_ipv4 *);
extern void rib_dump (const char *, const struct prefix_ipv4 *, const struct rib *);
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *);
#define ZEBRA_RIB_LOOKUP_ERROR -1
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 80a7279f..a4fa261b 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1614,6 +1614,62 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p)
}
}
+/* Check if requested address assignment will fail due to another
+ * route being installed by zebra in FIB already. Take necessary
+ * actions, if needed: remove such a route from FIB and deSELECT
+ * corresponding RIB entry. Then put affected RN into RIBQ head.
+ */
+void rib_lookup_and_pushup (struct prefix_ipv4 * p)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct rib *rib;
+ unsigned changed = 0;
+
+ if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
+ {
+ zlog_err ("%s: vrf_table() returned NULL", __func__);
+ return;
+ }
+
+ /* No matches would be the simplest case. */
+ if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
+ return;
+
+ /* Unlock node. */
+ route_unlock_node (rn);
+
+ /* Check all RIB entries. In case any changes have to be done, requeue
+ * the RN into RIBQ head. If the routing message about the new connected
+ * route (generated by the IP address we are going to assign very soon)
+ * comes before the RIBQ is processed, the new RIB entry will join
+ * RIBQ record already on head. This is necessary for proper revalidation
+ * of the rest of the RIB.
+ */
+ for (rib = rn->info; rib; rib = rib->next)
+ {
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
+ ! RIB_SYSTEM_ROUTE (rib))
+ {
+ changed = 1;
+ if (IS_ZEBRA_DEBUG_RIB)
+ {
+ char buf[INET_ADDRSTRLEN];
+ inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
+ zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
+ rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
+ }
+ rib_uninstall (rn, rib);
+ }
+ }
+ if (changed)
+ {
+ work_queue_aim_head (zebrad.ribq, 1);
+ rib_queue_add (&zebrad, rn);
+ work_queue_aim_head (zebrad.ribq, 0);
+ }
+}
+
int
rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
{