diff options
author | Tom Grennan <tgrennan@vyatta.com> | 2008-04-10 21:56:49 +0000 |
---|---|---|
committer | Tom Grennan <tgrennan@vyatta.com> | 2008-04-10 21:56:49 +0000 |
commit | c1bdabf8dd2f22a33fdc35b70b93e871f179445d (patch) | |
tree | 570e66e842fc556fc643e97aa37e0183ded19f56 | |
parent | db59fcc9e02b5755a92e4d2913420c1e09e05517 (diff) | |
parent | 9334b80b2c84f33d0d749b4a172f1d87a77a8544 (diff) | |
download | quagga-c1bdabf8dd2f22a33fdc35b70b93e871f179445d.tar.bz2 quagga-c1bdabf8dd2f22a33fdc35b70b93e871f179445d.tar.xz |
Merge branch 'upstream' into hollywood
Conflicts:
ChangeLog
zebra/zebra_rib.c
-rw-r--r-- | bgpd/ChangeLog | 30 | ||||
-rw-r--r-- | bgpd/bgp_attr.c | 25 | ||||
-rw-r--r-- | bgpd/bgp_attr.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_debug.c | 7 | ||||
-rw-r--r-- | bgpd/bgp_network.c | 9 | ||||
-rw-r--r-- | bgpd/bgp_open.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 13 | ||||
-rwxr-xr-x | configure.ac | 16 | ||||
-rw-r--r-- | isisd/ChangeLog | 11 | ||||
-rw-r--r-- | isisd/isis_flags.c | 19 | ||||
-rw-r--r-- | isisd/isis_flags.h | 1 | ||||
-rw-r--r-- | isisd/isisd.c | 8 | ||||
-rw-r--r-- | lib/ChangeLog | 32 | ||||
-rw-r--r-- | lib/linklist.c | 20 | ||||
-rw-r--r-- | lib/log.c | 29 | ||||
-rw-r--r-- | lib/log.h | 6 | ||||
-rw-r--r-- | lib/memory.c | 2 | ||||
-rw-r--r-- | lib/stream.h | 2 | ||||
-rw-r--r-- | ospf6d/ospf6_area.h | 6 | ||||
-rw-r--r-- | ospfd/ospf_opaque.h | 2 | ||||
-rw-r--r-- | ospfd/ospfd.h | 6 | ||||
-rw-r--r-- | ripd/ChangeLog | 6 | ||||
-rw-r--r-- | ripd/rip_interface.c | 1 | ||||
-rw-r--r-- | ripd/ripd.c | 1 | ||||
-rw-r--r-- | solaris/ChangeLog | 6 | ||||
-rw-r--r-- | solaris/Makefile.am | 2 | ||||
-rw-r--r-- | tests/ChangeLog | 8 | ||||
-rw-r--r-- | tests/aspath_test.c | 18 | ||||
-rw-r--r-- | tests/bgp_capability_test.c | 30 | ||||
-rw-r--r-- | zebra/ChangeLog | 28 | ||||
-rw-r--r-- | zebra/ioctl.c | 26 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 22 | ||||
-rw-r--r-- | zebra/rib.h | 1 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 56 |
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; @@ -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. */ @@ -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) { |