summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_snmp.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* bgpd: hook for bgp peer status change eventsMarton Kun-Szabo2019-08-131-1/+5
| | | | | | | | | | | Generally available hook for plugging application-specific code in for bgp peer change events. This hook (peer_status_changed) replaces the previous, more specific 'peer_established' hook with a more general-purpose one. Also, 'bgp_dump_state' is now registered under this hook. Signed-off-by: Marton Kun-Szabo <martonk@amazon.com>
* *: use array_size instead of raw divisionQuentin Young2019-02-261-8/+6
| | | | Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
* bgpd: Cleanup non-normal compiled code pathDonald Sharp2018-12-121-2/+2
| | | | | | | Looks like we missed some code in a non-normal compiled code path for the bgp_path_info conversion. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* bgpd: Abstract bgp_info retrieving/setting from info pointerDonald Sharp2018-11-161-2/+4
| | | | | | | | | The bgp_info data is stored as a void pointer in `struct bgp_node`. Abstract retrieval of this data and setting of this data into functions so that in the future we can move around what is stored in bgp_node. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* bgpd: fix missed info->path rename in snmpDavid Lamparter2018-10-161-1/+1
| | | | Signed-off-by: David Lamparter <equinox@diac24.net>
* bgpd: Convert binfo to pathDonald Sharp2018-10-091-22/+22
| | | | | | Convert the binfo variable to path. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* bgpd: Convert `struct bgp_info` to `struct bgp_path_info`Donald Sharp2018-10-091-6/+7
| | | | | | | | | | | | Do a straight conversion of `struct bgp_info` to `struct bgp_path_info`. This commit will setup the rename of variables as well. This is being done because `struct bgp_info` is not descriptive of what this data actually is. It is path information for routes that we keep to build the actual routes nexthops plus some extra information. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* bgpd: Implement group-overrides for peer timersPascal Mathis2018-06-141-5/+5
| | | | | | | | | | | | | | | | | | | This commit implements BGP peer-group overrides for the timer flags, which control the value of the hold, keepalive, advertisement-interval and connect connect timers. It was kept separated on purpose as the whole timer implementation is quite complex and merging this commit together with with the other flag implementations did not seem right. Basically three new peer flags were introduced, namely *PEER_FLAG_ROUTEADV*, *PEER_FLAG_TIMER* and *PEER_FLAG_TIMER_CONNECT*. The overrides work exactly the same way as they did before, but introducing these flags made a few conditionals simpler as they no longer had to compare internal data structures against eachother. Last but not least, the test suite has been adjusted accordingly to test the newly implemented flag overrides. Signed-off-by: Pascal Mathis <mail@pascalmathis.com>
* bgpd: fix and improve snmp peer lookupsPascal Mathis2018-05-111-20/+22
| | | | | | | | | | | | | | | | | | | The previous implementation of bgp_peer_lookup_next did not consider the internal ordering of peers when using peer groups, which led to all standalone peers being skipped that had a lower IP address than the highest IP address of a peer belonging to a group. As the ordering of peers can not be arbitrary due to SNMP requiring increasing OIDs when walking an OID tree, this commit fixes the bug by properly looping through all peers and detecting the next highest IP address. Additionally, this commit improved both bgp_peer_lookup_next and peer_lookup_addr_ipv4 by using the socketunion stored within the peer struct (peer->su) instead of calling inet_pton for each peer during comparison. Signed-off-by: Pascal Mathis <mail@pascalmathis.com>
* *: use C99 standard fixed-width integer typesQuentin Young2018-03-271-37/+37
| | | | | | | | | | | | | | | | | | | | | | The following types are nonstandard: - u_char - u_short - u_int - u_long - u_int8_t - u_int16_t - u_int32_t Replace them with the C99 standard types: - uint8_t - unsigned short - unsigned int - unsigned long - uint8_t - uint16_t - uint32_t Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
* *: conform with COMMUNITY.md formatting rules, via 'make indent'Lou Berger2018-03-061-2/+0
| | | | Signed-off-by: Lou Berger <lberger@labn.net>
* bgpd: use atomic_* ops on _Atomic variablesQuentin Young2018-01-091-9/+9
| | | | Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
* bgpd: fix various problems with hold/keepalive timersDon Slice2017-10-261-2/+2
| | | | | | | | | | | | | | | | | Problem reported that we weren't adjusting the keepalive timer correctly when we negotiated a lower hold time learned from a peer. While working on this, found we didn't do inheritance correctly at all. This fix solves the first problem and also ensures that the timers are configured correctly based on this priority order - peer defined > peer-group defined > global config. This fix also displays the timers as "configured" regardless of which of the three locations above is used. Ticket: CM-18408 Signed-off-by: Don Slice <dslice@cumulusnetworks.com> Reviewed-by: CCR-6807 Testing-performed: Manual testing successful, fix tested by submitter, bgp-smoke completed successfully
* Revert "*: reindent pt. 2"David Lamparter2017-07-221-0/+2
| | | | | | | | | This reverts commit c14777c6bfd0a446c85243d3a9835054a259c276. clang 5 is not widely available enough for people to indent with. This is particularly problematic when rebasing/adjusting branches. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* *: reindent pt. 2whitespace / reindent2017-07-171-2/+0
| | | | | | | | w/ clang 5 * reflow comments * struct members go 1 per line * binpack algo was adjusted
* *: reindentreindent-master-afterwhitespace / reindent2017-07-171-687/+730
| | | | | | indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'` Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* bgpd: Refactor 'struct attr_extra' into 'struct attr'Donald Sharp2017-07-121-8/+2
| | | | | | | | | | | | | | | | | Most of the attributes in 'struct attr_extra' allow for the more interesting cases of using bgp. The extra overhead of managing it will induce errors as we add more attributes and the extra memory overhead is negligible on anything but full bgp feeds. Additionally this greatly simplifies the code for the handling of data. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> bgpd: Fix missing label set Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* *: make consistent & update GPLv2 file headersDavid Lamparter2017-05-151-18/+18
| | | | | | | | | | | The FSF's address changed, and we had a mixture of comment styles for the GPL file header. (The style with * at the beginning won out with 580 to 141 in existing files.) Note: I've intentionally left intact other "variations" of the copyright header, e.g. whether it says "Zebra", "Quagga", "FRR", or nothing. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* *: snmp: convert into modulesDavid Lamparter2017-03-251-8/+21
| | | | Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* *: use hooks for sending SNMP trapsDavid Lamparter2017-03-251-5/+11
| | | | | | | This means there are no ties into the SNMP code anymore other than the init call at startup. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* lib, bgpd, tests: Refactor FILTER_X in zebra.hDonald Sharp2016-08-161-0/+1
| | | | | | | | lib/zebra.h has FILTER_X #define's. These do not belong there. Put them in lib/filter.h where they belong. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> (cherry picked from commit 0490729cc033a3483fc6b0ed45085ee249cac779)
* *: snmp: add a load of "static" specifiersDavid Lamparter2016-07-281-4/+4
| | | | | | | Make it easier to see which bits in *_snmp.c are actually referenced from non-SNMP parts of the code. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* *: fix in_addr initialisersDavid Lamparter2016-05-261-1/+1
| | | | | Signed-off-by: David Lamparter <equinox@opensourcerouting.org> (cherry picked from commit 5181a0296687a6004dd00c7c0874886c9ff0bf60)
* bgpd: fix SNMP write supportDavid Lamparter2016-05-261-18/+20
| | | | | | | | | | | | | | | This code - dating back to the initial import in 2002 - probably never worked. Calling asn_parse_int seems to always have been wrong, and in the meantime, there no longer is a "struct variable *" argument for write_method. If anyone tried to use it, it'd probably have crashed. (I didn't try.) Fix this up so it actually works. It's the only place in Quagga where a SNMP write is actually supported, so it's an odd one out anyway, but heh. Signed-off-by: David Lamparter <equinox@opensourcerouting.org> (cherry picked from commit d689d1a0c69726330d69b2dd412fdb8dcb23394b)
* Use a hash to store BGP peer structuresDaniel Walton2015-10-231-1/+3
| | | | | | | Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Ticket: CM-5370
* Remove BGP's asorig timer, it is no longer usedDaniel Walton2015-10-201-12/+2
| | | | | Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
* bgpd: backout change of bm->master and masterDonald Sharp2015-10-131-1/+1
| | | | | | | Upstream does wanted the reverse of what was done in this patch. Back out the patch. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* bgpd: fix using of two pointers for struct thread_masterDonald Sharp2015-09-241-1/+1
| | | | | | | | bgp is using both bm->master and master pointers interchangebly for thread manipulation. Since they are the same thing consolidate to one pointer. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
* *: nuke ^L (page feed)David Lamparter2014-06-041-4/+4
| | | | | | | | | | | | | | Quagga sources have inherited a slew of Page Feed (^L, \xC) characters from ancient history. Among other things, these break patchwork's XML-RPC API because \xC is not a valid character in XML documents. Nuke them from high orbit. Patches can be adapted simply by: sed -e 's%^L%%' -i filename.patch (you can type page feeds in some environments with Ctrl-V Ctrl-L) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* snmp: let handlers accept OID from a lesser prefixVincent Bernat2012-06-251-1/+6
| | | | | | | | | Most table handlers do not expect to be given an OID whose prefix is outside what they can handle. This is not a problem with the SMUX implementation since it always correct the OID such that the prefix matches. However, this is not the case for the AgentX implementation. A new function, smux_header_table() is used to do this normalization.
* agentx: handle SNMP trapsVincent Bernat2012-06-251-2/+7
| | | | | | | | | | | | | | | | smux_trap() signature has been changed to provide appropriate level information to send SNMPv2 notifications. This includes the addition of the enterprise OID to use (from which is derived the SNMP trap OID) and the MIB registry to locate the appropriate function for variable bindings provided by the trap. The SMUX implementation has been updated but ignore the provided enterprise OID. Instead, it still uses the SMUX peer OID to keep compatibility with previous versions of Quagga. The SMUX implementation also ignores the provided MIB registry since it uses smux_get() function to grab the appropriate values. This is not possible with the AgentX implementation since there is no such function provided by NetSNMP.
* smux: drop findVar element from trap object structVincent Bernat2012-06-251-2/+2
| | | | This element was not unused.
* smux: remove `tick` argument from smux_trap()Vincent Bernat2012-06-251-2/+2
| | | | | | | | | smux_trap() contains an argument whose use appears to be to set sysUpTime.0/timestamp field in SNMP trap. However, this value is not used in smux_trap(). Moreover, it is expected that this field is the value of sysUpTime.0 when the trap was sent and not any other time related to the trap. To avoid any confusion, we remove this field from the signature of the function.
* build: only define HAVE_SNMPVincent Bernat2012-06-251-6/+0
| | | | | NetSNMP is the only SNMP implementation for Quagga. We don't need two different symbols.
* bgp: use monotonic clock for time of dayStephen Hemminger2010-01-151-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | BGP uses time() to get system time of day; but that value fluctuates with time adjustments from NTP. This can cause premature flapping of peer sessions and other failures. Use the system monotonic clock supported by Quagga thread library to avoid issue. See: http://bugzilla.vyatta.com/show_bug.cgi?id=4467 * bgpd/bgp_fsm.c * bgp_uptime_reset(): dismiss function * bgpd/bgpd.c * bgp_clock(): new function * bgpd/bgp_damp.c * bgp_reuse_timer(): employ bgp_clock() instead of time(NULL) * bgp_damp_withdraw(): idem * bgp_damp_update(): idem * bgp_damp_scan(): idem * bgp_damp_info_vty(): idem * bgp_damp_reuse_time_vty(): idem * bgpd/bgp_fsm.c * bgp_routeadv_timer(): idem * bgp_stop(): idem * bgp_establish(): idem * bgpd/bgp_packet.c * bgp_update_receive(): idem * bgpd/bgp_route.c * bgp_update_rsclient(): idem * bgp_update_main(): idem * bgp_static_update_rsclient(): idem * bgp_static_update_main(): idem * bgp_static_update_vpnv4(): idem * bgp_aggregate_route(): idem * bgp_aggregate_add(): idem * bgp_redistribute_add(): idem * bgpd/bgp_snmp.c * bgpPeerTable(): idem * bgpTrapEstablished(): idem * bgpTrapBackwardTransition(): idem * bgpd/bgpd.c * peer_create(): idem * peer_uptime(): idem * bgp_master_init(): idem
* [cleanup] functions taking no args should be declared with void argsStephen Hemminger2009-06-121-1/+1
| | | | | Use Ansi-C prototypes rather than old K&R method of declaring function without arguments
* [snmp] Compiler warning fixes for when "--enable-snmp" is configured.Chris Caputo2009-06-021-16/+23
| | | | | Compiled on 32-bit and 64-bit linux gcc 4.1.2 platforms. No run-time testing on 32-bit and limited run-time testing on 64-bit.
* Make --enable-snmp cross compile and make libcrypto optional with ↵Joakim Tjernlund2008-08-251-1/+3
| | | | | | | --without-crypto Autoconfig work by me, the rest was done by "Kirill K. Smirnov" <lich@math.spbu.ru>
* [bgpd] Trim memory usage of BGP routesPaul Jakma2007-05-041-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 2007-05-03 Paul Jakma <paul.jakma@sun.com> * bgp_route.h: (struct info) Move less frequently used fields to a lazily allocated struct info_extra. Export bgp_info_extra_get * bgp_route.c: (bgp_info_extra_new) allocate extra (bgp_info_extra_free) Free damp info and the info_extra. (bgp_info_extra_get) Retrieve the info_extra of a struct info, allocating as required. (generally) adjust to use info->extra * bgp_damp.c: (generally) use bgp_info_extra_get to access dampinfo * bgp_attr.h: Move rarely allocated attributes from struct attr to a struct attr_extra, for a substantial saving in size of struct attr. * bgp_attr.c: (bgp_attr_extra_{new,free}), new, self-explanatory. (bgp_attr_extra_get) Get the attr_extra for a given struct attr, allocating it if needs be. (bgp_attr_dup) Shallow copy the struct attr and its attr_extra. (generally) adjust to know about attr->extra. * bgp_debug.c: (bgp_dump_attr) ditto * bgp_vty.c: (show_bgp_memory) print attr and info extra sizes. * bgp_nexthop.c: (generally) adjust to know about attr->extra and info->extra. * bgp_{packet,routemap,snmp,zebra}.c: ditto * lib/memtypes.c: Add MTYPE_ATTR_EXTRA and MTYPE_BGP_ROUTE_EXTRA
* 2005-09-10 Paul Jakma <paul.jakma@sun.com>paul2005-09-101-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Makefile.am: bgpd shouldn't list libgp's sources as its own. Use LDADD. * bgp_aspath.h: (struct assegment) New struct, abstract representation of a list of AS_PATH segments and the contained ASNs. (struct aspath) Remove the raw-data related fields, reference the abstract struct assegment instead. Remove several other computed fields, it's just a headache to maintain them and they're cheap to compute from struct assegment. (aspath_parse) parse a stream, not a pointer to raw data. (aspath_count_{hops,confeds,size}) helpers to access information formerly directly contained in struct aspath. (aspath_snmp_pathseg) Helper for SNMP, BGP MIB wants to be able to output hex representation of raw data. * bgp_aspath.c: (general) partial-rewrite. Store aspath data as an abstract singly-linked list of abstract segments, rather than storing the raw data, and parsing it each and every time. Remove several count/size fields which are cheap to compute from the abstract segment structure. (global) Include stream.h, needed for aspath_parse, and others. Couple of helper macros added. (struct assegment_header) Just the header, and only the header. (assegment_data_{new,free}) convenience functions for AS_SEG_DATA allocation, the dynamic, per-segment array of ASNs. (assegment_{new,free,free_all,dup,dup_all}) convenience functions for creating struct assegments. The _all forms will follow the entire chain of segments from the given segment. (assegment_prepend_asns) new function, prepend an ASN N times to segment. (assegment_append_asns) Append a list (array) of ASNs to segment. (int_cmp) convenience function for the aspath hash. (assegment_normalise) new function. Normalise the given segment chain to meet expectations of Quagga, and to eliminate differing raw representations of the same paths. Merge 'runs' of SEQUENCEs into one segment as our internal segment is not limited by the protocol AS_PATH segment length. Sort ASNs in SETs. (aspath_new) Take void argument to quell warnings. Use the assegment convenience functions. (assegment_count_{asns,confeds,hops}) new functions to compute at runtime values previously held in struct aspath. (aspath_size) ditto. (aspath_make_str_count) rewritten to stringify new representation, and to be slightly easier to understand hopefully. (aspath_str_update) convenience function, update the aspath str. Should investigate removing maintained string from struct aspath, just run-time compute it, as per other fields. It's just a maintenance headache, would save noticeable amount of RAM with possibly not much extra run-time cost. (aspath_dup) use the assegment dup functions. (aspath_hash_alloc) Take void * argument to satisfy gcc. Use the proper helper functions to dup data. (assegments_parse) new function. parse raw AS_PATH data into struct assegments. Normalise and return the head of the list. (aspath_parse) Parse a stream, not pointer to raw data and use assegments_parse to do it. (assegment_data_put) Write out a single segment data in protocol form to stream. (assegment_header_put) ditto but for segment header. (aspath_put) new function. As per previous but for an entire struct aspath. (aspath_snmp_pathseg) wrapper around aspath_put for bgp_snmp.c. Uses a static buffer sadly. (aspath_aggregate_as_set_add) rewritten to use assegments. (aspath_aggregate) ditto (aspath_{firstas,loop,private_as}_check) ditto (aspath_{merge,prepend,add_one_as}) ditto (aspath_cmp_left{_confed}) ditto (aspath_delete_confed_seq) ditto, plus fixed to properly delete all leading confed segments. (aspath_as_add) Just use assegment_append_asns. (aspath_segment_add) updated to use assegments. (enum as_token) Add values for confeds (aspath_gettoken) Add support for confeds (aspath_str2aspath) ditto (aspath_key_make) updated to use as_segments. Also, add segment type into the hash value as appropriate. (aspath_cmp) updated to use as_segments. (aspath_print) don't segfault on NULL argument. * bgp_attr.c: (bgp_attr_aspath) aspath_parse wants the stream now. No need for manual forwarding of stream. (bgp_packet_attribute) empty aspath is now denoted by NULL segment field, length is gone. Use aspath_size() to determine size. (bgp_attr_init) Fix declaration, explicitely specify void arg. (bgp_dump_routes_attr) Use aspath_size() to determine size. * bgp_route.c: (bgp_info_cmp) use the aspath_count_* functions. (bgp_rib_withdraw) remove unused variable. Use aspath_count_hops. * bgp_snmp.c: (bgp4PathAttrTable) raw data is gone, use aspath_snmp_pathseg to get the representation.
* 2005-04-07 Paul Jakma <paul.jakma@sun.com>paul2005-04-071-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * (global): Fix up list loops to match changes in lib/linklist, and some basic auditing of usage. * configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES * HACKING: Add notes about deprecating interfaces and commands. * lib/linklist.h: Add usage comments. Rename getdata macro to listgetdata. Rename nextnode to listnextnode and fix its odd behaviour to be less dangerous. Make listgetdata macro assert node is not null, NULL list entries should be bug condition. ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use with for loop, Suggested by Jim Carlson of Sun. Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the "safety" of previous macro. LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to distinguish from the similarly named functions, and reflect their effect better. Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section with the old defines which were modified above, for backwards compatibility - guarded to prevent Quagga using it.. * lib/linklist.c: fix up for linklist.h changes. * ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single scan of the area list, rather than scanning all areas first for INTER_ROUTER and then again for INTER_NETWORK. According to 16.2, the scan should be area specific anyway, and further ospf6d does not seem to implement 16.3 anyway.
* * bgp_attr.c, bgp_snmp.c, bgp_vty.c, bgpd.[ch]: Remove support for oldhasso2005-02-011-1/+1
| | | | | | | draft - ie. "neighbor version 4-" commands. Preserve dummy "neighbor version" command as deprecated. [merge from GNU Zebra]
* * bgp_nexthop.c: Improve debug.hasso2005-02-011-5/+0
| | | | | | | | | | | | | * bgpd.[ch], bgp_nexthop.c, bgp_snmp.c: Remove useless bgp_get_master() function. * bgp_packet.c: MP AFI_IP update and withdraw parsing. * bgp_fsm.c: Reset peer synctime in bgp_stop(). bgp_fsm_change_status() is better place to log about peer status change than bgp_event(). Log in bgp_connect_success(). * bgp_vty.c: Fix typo in comment. * bgp_attr.c: Better log about unknown attribute. [merge from GNU Zebra]
* Make initializing smux connection configurable - "smux peer OID" commandhasso2004-10-131-7/+1
| | | | | initializes connection, and "no smux peer" command terminates it. Fixes bugzilla #47 and #112.
* 2004-10-13 Paul Jakma <paul@dishone.st>paul2004-10-131-1/+1
| | | | | | | | | | | * (global) more const'ification and fixups of types to clean up code. * bgp_mplsvpn.{c,h}: (str2tag) fix abuse. Still not perfect, should use something like the VTY_GET_INTEGER macro, but without the vty_out bits.. * bgp_routemap.c: (set_aggregator_as) use VTY_GET_INTEGER_RANGE (no_set_aggregator_as) ditto. * bgpd.c: (peer_uptime) fix unlikely bug, where no buffer is returned, add comments about troublesome return value.
* 2003-06-19 Paul Jakma <paul@dishone.st>paul2003-06-191-1/+7
| | | | | * Fix lib/smux.c's reliance on daemons exporting struct thread_master *master.
* Import of zebra.org 20030428-18:07 ISTpaul2003-04-281-1/+0
|
* 2003-04-04 Paul Jakma <paul@dishone.st>paul2003-04-041-2/+6
| | | | | | | | | * Sync to Zebra CVS * Fix lib/thread.h leak * Fix small Opaque LSA leak * Do not configure OSPF interfaces for secondary addresses * vtysh fixes from Hasso * Dave Watson's missing ntohs fix
* Fix build for net-snmppaul2003-03-181-1/+4
|
* Initial revisionpaul2002-12-131-0/+875