From dfc1d5caacfe0346499f2eceff18d56af0b85e2f Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 8 Dec 2010 18:51:37 +0300 Subject: bgpd: fix community-list error message spelling * bgp_vty.c: (community_list_perror, show_ip_community_list_arg, show_ip_extcommunity_list_arg) fix spelling (cherry picked from commit b729294c8c5c6f2af8ddf6cfbea2374b6faabe9d) --- bgpd/bgp_vty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 88be52e2..ec0106a8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9952,7 +9952,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 +10313,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 +10663,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; } -- cgit v1.2.1 From a1239bc50d26ce963352f8ddaa6c1382e437d286 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Thu, 13 Jan 2011 18:25:40 +0300 Subject: ospf6d: fix crash in SPF calculation * ospf6_spf.c: Don't replace a node with another node with a lower number of hops, instead get them from the queue in the correct order. (Actually, the replacement crashed the ospf6d daemon rather than worked.) (cherry picked from commit 403138e189c24f6867824c4eeb668d11564e1ca0) --- ospf6d/ospf6_spf.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index bfb6df2e..04367f08 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; } -- cgit v1.2.1 From bbccf41f8e5fb83831da81a339a578a3d5fc5f4a Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Fri, 14 Jan 2011 18:27:05 +0300 Subject: bgpd: fix handling of "Unsupported Capability" * bgp_packet.c: (bgp_notify_receive) justify the difference between BGP_NOTIFY_OPEN_UNSUP_PARAM and BGP_NOTIFY_OPEN_UNSUP_CAPBL cases, as it is explained in RFC5492, page 3, paragraph 1. "Unsupported Capability" error does not mean, that the peer doesn't support capabilities advertisement -- quite the opposite (if the peer would not support capabilities advertisement, the code would be "Unsupported Optional Parameter"). Thus there is no reason to mark the peer as one non-supporting capabilities advertisement. Example: suppose the peer is in fact IPv6-only, but we didn't configure anything address-family specific for it. Then, the peer would refuse the session with "Unsupported Capability" code. If we internally set the peer as non-supporting capabilities advertisement after that, we will not be able to establish the session with it ever, even with a fixed configuration -- IPv6-only BGP session cannot be established without capabilities. In practice an edge case would be seen as the same IPv6 peer working with its "neighbor" block read from bgpd.conf, but not working, when slowly input in "conf t" mode. (cherry picked from commit c7aa8abd8788c3607ad0131f02e892cf92221e40) --- bgpd/bgp_packet.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index a5f9552c..9102add7 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1885,12 +1885,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); } -- cgit v1.2.1 From 16ac59798e0bafc5083ae4b3be2c3edd89a62e5f Mon Sep 17 00:00:00 2001 From: David Ward Date: Mon, 17 Jan 2011 10:58:52 +0300 Subject: bgpd: VTY string fixes for debug commands * bgpd/bgp_debug.c: fix VTY strings for BGP debug commands to match correct syntax (cherry picked from commit 6e22b9017e1ae2ce61c383b1b2b63973207704ac) --- bgpd/bgp_debug.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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") -- cgit v1.2.1 From 49efb768502ddb1bb78d609c25b3818c6a519a2a Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 24 Feb 2011 13:52:14 +0300 Subject: ripd: resolve debug statements issue (bug 442) ...A nasty bug, if you forgot to disable debugging, stored the config and reboot your machine - if you really depend on ripd, then the machine will not fully come back on the network, because ripd fails. (cherry picked from commit 0fa0335316ce14a79ea4bbb0c40e1322c9941dd3) --- ripd/rip_debug.c | 24 +++++++++--------------- ripd/rip_debug.h | 1 - 2 files changed, 9 insertions(+), 16 deletions(-) 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) -- cgit v1.2.1 From f668053f1453d64296db6807101450ad749ba730 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 18 Mar 2011 20:20:53 +0300 Subject: doc: fix "ipv6 address" interface command syntax (#608) (cherry picked from commit e6844aa5d23cf56dd1f31afc96e8145ab188953f) --- doc/main.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 -- cgit v1.2.1 From fc09716b81e67f2d06dc92ff7bcb1efdf18c4eec Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 5 Dec 2010 17:17:26 +0000 Subject: bgpd/security: CVE-2010-1674 Fix crash due to extended-community parser error * bgp_attr.c: (bgp_attr_ext_communities) Certain extended-community attrs can leave attr->flag indicating ext-community is present, even though no extended-community object has been attached to the attr structure. Thus a null-pointer dereference can occur later. (bgp_attr_community) No bug fixed here, but tidy up flow so it has same form as previous. Problem and fix thanks to anonymous reporter. (cherry picked from commit 0c46638122f10019a12ae9668aec91691cf2e017) --- bgpd/bgp_attr.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index ae0dc88a..c6fd3a57 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1235,13 +1235,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; @@ -1478,13 +1481,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; -- cgit v1.2.1 From e70e575a8cb1edcab2eedade04bb4ac31938bddf Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Tue, 5 Jul 2011 00:41:59 +0400 Subject: bgpd: Remove AS Path limit/TTL functionality * draft-ietf-idr-as-pathlimit doesn't seem to have gone anywhere, and its author does not think it will make progress in IDR. Remove all support introduced for it, but leave stubs for the commands to avoid breaking any configurations. Basically reverts cecab5e9725792e60a5e4b473e238a14cd85815d. (cherry picked from commit c8f3fe3063cb9ff193b13011cfbda3e605395340) Conflicts: bgpd/bgp_attr.c (caused by c8e7b895, resolved) --- bgpd/bgp_attr.c | 77 +------- bgpd/bgp_attr.h | 6 - bgpd/bgp_route.c | 551 +++++++++++++++++----------------------------------- bgpd/bgp_route.h | 3 - bgpd/bgp_routemap.c | 121 ++---------- doc/bgpd.texi | 23 --- doc/routemap.texi | 14 -- 7 files changed, 195 insertions(+), 600 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index c6fd3a57..aa6fa613 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -359,11 +359,6 @@ attrhash_key_make (void *p) 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) { @@ -415,9 +410,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 +697,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, @@ -1717,9 +1673,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; @@ -2274,24 +2227,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); @@ -2503,16 +2438,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_route.c b/bgpd/bgp_route.c index 1cfc4511..75a59cb4 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) @@ -3239,14 +3193,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); @@ -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); @@ -3626,44 +3564,17 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_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, - afi_t afi, safi_t 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)) { @@ -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 /, 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 /, 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 /, 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 /, 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", @@ -4283,15 +4063,6 @@ DEFUN (no_bgp_network, bgp_node_safi (vty)); } -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 /, 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", @@ -4309,16 +4080,6 @@ ALIAS (no_bgp_network, "IP prefix /, 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 /, 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 /\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 /\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 /\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,127 @@ ALIAS (no_ipv6_bgp_network, "Specify a network to announce via BGP\n" "IPv6 prefix /, 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 /, 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 /, 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 /, 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 /, 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") +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 /\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 /\n" + "AS-Path hopcount limit attribute\n" + "AS-Pathlimit TTL, in number of AS-Path hops\n") /* Aggreagete address: @@ -6130,17 +5948,6 @@ 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); @@ -11548,8 +11355,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); @@ -11638,12 +11443,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); @@ -11653,12 +11452,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); @@ -11688,23 +11481,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); @@ -11733,24 +11516,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); @@ -11971,10 +11742,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); @@ -12293,6 +12062,52 @@ 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); + + install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd); } 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..81ff48db 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 @@ -3743,17 +3651,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 +3669,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 +3680,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 +3698,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 +3861,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/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/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 -- cgit v1.2.1 From 878715cc78de825894d83458b7c8bd68e3f347cc Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 12 Jul 2011 17:14:13 +0400 Subject: version RE-0.99.17.1 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 41a6f9b1..697453cb 100755 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ ## $Id$ AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.17, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.17.1, [https://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) -- cgit v1.2.1 From ab1be8a20de4db0d17e28483660627fd843845f1 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Fri, 22 Apr 2011 19:27:54 +0400 Subject: ospf6d: copy "mtu-ignore" option from ospfd "mtu-ignore" is an option ospfd used to mimic from the vendor's implementation, now ospf6d will also implement it. * ospf6_interface.h: extend ospf6_interface structure by one flag * ospf6_interface.c: (ipv6_ospf6_mtu_ignore, no_ipv6_ospf6_mtu_ignore): new declarations; (ospf6_interface_create): show initial value for consistency; (ospf6_interface_show): print flag status * ospf6_message.c: (ospf6_dbdesc_recv): consider interface-specific flag when checking MTU --- ospf6d/ospf6_interface.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ ospf6d/ospf6_interface.h | 3 +++ ospf6d/ospf6_message.c | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) 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_message.c b/ospf6d/ospf6_message.c index 790fc0ae..4648c459 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"); -- cgit v1.2.1 From 82a963a1b8d9066f5e3e24e98b65398d32a73876 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Tue, 12 Jul 2011 17:53:33 +0400 Subject: ospf6d: check MTU with message header size in mind * ospf6_message.c: (ospf6_packet_max): new function, return maximum IPv6 payload on an interface; (ospf6_hello_send, ospf6_dbdesc_send, ospf6_dbdesc_send_newone, ospf6_lsreq_send, ospf6_lsupdate_send_neighbor, ospf6_lsupdate_send_interface, ospf6_lsack_send_neighbor, ospf6_lsack_send_interface): compare message size with the maximum payload instead of the MTU. --- ospf6d/ospf6_message.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 4648c459..4db19da7 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -42,6 +42,8 @@ #include "ospf6_flood.h" #include "ospf6d.h" +#include + unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0}; const char *ospf6_message_type_str[] = { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" }; @@ -1357,6 +1359,12 @@ ospf6_send (struct in6_addr *src, struct in6_addr *dst, zlog_err ("Could not send entire message"); } +static int +ospf6_packet_max(struct ospf6_interface *oi) +{ + return oi->ifmtu - sizeof(struct ip6_hdr); +} + int ospf6_hello_send (struct thread *thread) { @@ -1403,7 +1411,7 @@ ospf6_hello_send (struct thread *thread) if (on->state < OSPF6_NEIGHBOR_INIT) continue; - if (p - sendbuf + sizeof (u_int32_t) > oi->ifmtu) + if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi)) { if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND)) zlog_debug ("sending Hello message: exceeds I/F MTU"); @@ -1479,7 +1487,7 @@ ospf6_dbdesc_send (struct thread *thread) /* MTU check */ if (p - sendbuf + sizeof (struct ospf6_lsa_header) > - on->ospf6_if->ifmtu) + ospf6_packet_max(on->ospf6_if)) { ospf6_lsa_unlock (lsa); break; @@ -1513,7 +1521,7 @@ ospf6_dbdesc_send_newone (struct thread *thread) for (lsa = ospf6_lsdb_head (on->summary_list); lsa; lsa = ospf6_lsdb_next (lsa)) { - if (size + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu) + if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { ospf6_lsa_unlock (lsa); break; @@ -1580,7 +1588,7 @@ ospf6_lsreq_send (struct thread *thread) lsa = ospf6_lsdb_next (lsa)) { /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > on->ospf6_if->ifmtu) + if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if)) { ospf6_lsa_unlock (lsa); break; @@ -1649,7 +1657,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread) { /* MTU check */ if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) - > on->ospf6_if->ifmtu) + > ospf6_packet_max(on->ospf6_if)) { ospf6_lsa_unlock (lsa); break; @@ -1669,7 +1677,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread) { /* MTU check */ if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) - > on->ospf6_if->ifmtu) + > ospf6_packet_max(on->ospf6_if)) { ospf6_lsa_unlock (lsa); break; @@ -1742,7 +1750,7 @@ ospf6_lsupdate_send_interface (struct thread *thread) { /* MTU check */ if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header))) - > oi->ifmtu) + > ospf6_packet_max(oi)) { ospf6_lsa_unlock (lsa); break; @@ -1809,7 +1817,7 @@ ospf6_lsack_send_neighbor (struct thread *thread) lsa = ospf6_lsdb_next (lsa)) { /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu) + if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { /* if we run out of packet size/space here, better to try again soon. */ @@ -1869,7 +1877,7 @@ ospf6_lsack_send_interface (struct thread *thread) lsa = ospf6_lsdb_next (lsa)) { /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsa_header) > oi->ifmtu) + if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi)) { /* if we run out of packet size/space here, better to try again soon. */ -- cgit v1.2.1 From ea15b20a7cb8e41e61c48e36a554c576ed6f2f91 Mon Sep 17 00:00:00 2001 From: heasley Date: Tue, 12 Jul 2011 20:09:18 +0400 Subject: bgpd: consistent log msg format (BZ#565) --- bgpd/bgp_attr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index aa6fa613..3f4b3ce4 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1553,7 +1553,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, { /* XXX warning: long int format, int arg (arg 5) */ zlog (peer->log, LOG_WARNING, - "%s error BGP attribute length %lu is smaller than min len", + "%s: error BGP attribute length %lu is smaller than min len", peer->host, (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer)))); @@ -1573,7 +1573,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) { zlog (peer->log, LOG_WARNING, - "%s Extended length set, but just %lu bytes of attr header", + "%s: Extended length set, but just %lu bytes of attr header", peer->host, (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer)))); @@ -1596,7 +1596,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, if (CHECK_BITMAP (seen, type)) { zlog (peer->log, LOG_WARNING, - "%s error BGP attribute type %d appears twice in a message", + "%s: error BGP attribute type %d appears twice in a message", peer->host, type); bgp_notify_send (peer, @@ -1616,7 +1616,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, if (attr_endp > endp) { zlog (peer->log, LOG_WARNING, - "%s BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p", peer->host, type, length, size, attr_endp, endp); + "%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p", peer->host, type, length, size, attr_endp, endp); bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); @@ -1708,7 +1708,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, if (BGP_INPUT_PNT (peer) != endp) { zlog (peer->log, LOG_WARNING, - "%s BGP attribute %s, length mismatch", + "%s: BGP attribute %s, length mismatch", peer->host, LOOKUP (attr_str, type)); bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, -- cgit v1.2.1 From 87f011e5297ab9d3c599916800aab1198613071e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 13 Jul 2011 16:53:13 +0400 Subject: bgpd: fix SAFI for for MPLS labeled VPN-IPv6 * bgpd.h: change value of BGP_SAFI_VPNV6 to 128 (RFC4659, BZ#659) * bgp_route.c: (bgp_table_stats_vty) fix length argument to strncmp() --- bgpd/bgp_route.c | 2 +- bgpd/bgpd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 75a59cb4..1da5d1da 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -9090,7 +9090,7 @@ bgp_table_stats_vty (struct vty *vty, const char *name, safi = SAFI_UNICAST; else if (strncmp (safi_str, "vpnv4", 5) == 0) safi = BGP_SAFI_VPNV4; - else if (strncmp (safi_str, "vpnv6", 6) == 0) + else if (strncmp (safi_str, "vpnv6", 5) == 0) safi = BGP_SAFI_VPNV6; else { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index a5afaedc..73a9ea12 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -726,7 +726,7 @@ struct bgp_nlri /* SAFI which used in open capability negotiation. */ #define BGP_SAFI_VPNV4 128 -#define BGP_SAFI_VPNV6 129 +#define BGP_SAFI_VPNV6 128 /* Max TTL value. */ #define TTL_MAX 255 -- cgit v1.2.1 From e81537d3be9f95d333d658329e5d69e6188b53c0 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 14 Jul 2011 12:36:19 +0400 Subject: bgpd: more SAFI fixes Two macros resolving to the same integer constant broke a case block and a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was performed. * bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single * macro * bgp_capability_test.c: update test data * bgp_mp_attr_test.c: idem * bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update macro and check conditions (where appropriate) * bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send, bgp_update_receive, bgp_route_refresh_receive): idem * bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices, bgp_open_capability_orf, bgp_open_capability): idem * bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute, bgp_packet_withdraw): idem --- bgpd/bgp_attr.c | 8 ++++---- bgpd/bgp_open.c | 21 ++++++--------------- bgpd/bgp_packet.c | 14 +++++++------- bgpd/bgp_route.c | 15 +++------------ bgpd/bgpd.h | 5 ++--- tests/bgp_capability_test.c | 19 ++++++------------- tests/bgp_mp_attr_test.c | 12 ++++++------ 7 files changed, 34 insertions(+), 60 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 3f4b3ce4..f34a7565 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1367,7 +1367,7 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, return -1; } - if (safi != BGP_SAFI_VPNV4) + if (safi != SAFI_MPLS_LABELED_VPN) { ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), nlri_len); if (ret < 0) @@ -1411,7 +1411,7 @@ bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length, withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE; - if (safi != BGP_SAFI_VPNV4) + if (safi != SAFI_MPLS_LABELED_VPN) { ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), withdraw_len); if (ret < 0) @@ -2094,7 +2094,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, sizep = stream_get_endp (s); stream_putc (s, 0); /* Length of this attribute. */ stream_putw (s, AFI_IP); /* AFI */ - stream_putc (s, BGP_SAFI_VPNV4); /* SAFI */ + stream_putc (s, SAFI_MPLS_LABELED_VPN); /* SAFI */ stream_putc (s, 12); stream_putl (s, 0); @@ -2257,7 +2257,7 @@ bgp_packet_withdraw (struct peer *peer, struct stream *s, struct prefix *p, if (safi == SAFI_MPLS_VPN) { /* SAFI */ - stream_putc (s, BGP_SAFI_VPNV4); + stream_putc (s, SAFI_MPLS_LABELED_VPN); /* prefix. */ stream_putc (s, p->prefixlen + 88); diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 37595817..21c7e367 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -96,8 +96,8 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer) case SAFI_UNICAST_MULTICAST: vty_out (vty, "SAFI Unicast Multicast"); break; - case BGP_SAFI_VPNV4: - vty_out (vty, "SAFI MPLS-VPN"); + case SAFI_MPLS_LABELED_VPN: + vty_out (vty, "SAFI MPLS-labeled VPN"); break; default: vty_out (vty, "SAFI Unknown %d ", mpc.safi); @@ -127,14 +127,6 @@ bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc) int bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi) { - /* VPNvX are AFI specific */ - if ((afi == AFI_IP6 && *safi == BGP_SAFI_VPNV4) - || (afi == AFI_IP && *safi == BGP_SAFI_VPNV6)) - { - zlog_warn ("Invalid afi/safi combination (%u/%u)", afi, *safi); - return 0; - } - switch (afi) { case AFI_IP: @@ -143,9 +135,8 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi) #endif switch (*safi) { - /* BGP VPNvX SAFI isn't contigious with others, remap */ - case BGP_SAFI_VPNV4: - case BGP_SAFI_VPNV6: + /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */ + case SAFI_MPLS_LABELED_VPN: *safi = SAFI_MPLS_VPN; case SAFI_UNICAST: case SAFI_MULTICAST: @@ -859,7 +850,7 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer, int number_of_orfs = 0; if (safi == SAFI_MPLS_VPN) - safi = BGP_SAFI_VPNV4; + safi = SAFI_MPLS_LABELED_VPN; stream_putc (s, BGP_OPEN_OPT_CAP); capp = stream_get_endp (s); /* Set Capability Len Pointer */ @@ -967,7 +958,7 @@ bgp_open_capability (struct stream *s, struct peer *peer) stream_putc (s, CAPABILITY_CODE_MP_LEN); stream_putw (s, AFI_IP); stream_putc (s, 0); - stream_putc (s, BGP_SAFI_VPNV4); + stream_putc (s, SAFI_MPLS_LABELED_VPN); } #ifdef HAVE_IPV6 /* IPv6 unicast. */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 9102add7..6c170ab6 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -939,7 +939,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi, /* Adjust safi code. */ if (safi == SAFI_MPLS_VPN) - safi = BGP_SAFI_VPNV4; + safi = SAFI_MPLS_LABELED_VPN; s = stream_new (BGP_MAX_PACKET_SIZE); @@ -1029,7 +1029,7 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi, /* Adjust safi code. */ if (safi == SAFI_MPLS_VPN) - safi = BGP_SAFI_VPNV4; + safi = SAFI_MPLS_LABELED_VPN; s = stream_new (BGP_MAX_PACKET_SIZE); @@ -1761,17 +1761,17 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) { if (mp_update.length && mp_update.afi == AFI_IP - && mp_update.safi == BGP_SAFI_VPNV4) + && mp_update.safi == SAFI_MPLS_LABELED_VPN) bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update); if (mp_withdraw.length && mp_withdraw.afi == AFI_IP - && mp_withdraw.safi == BGP_SAFI_VPNV4) + && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN) bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw); if (! withdraw_len && mp_withdraw.afi == AFI_IP - && mp_withdraw.safi == BGP_SAFI_VPNV4 + && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN && mp_withdraw.length == 0) { /* End-of-RIB received */ @@ -1942,7 +1942,7 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size) /* Check AFI and SAFI. */ if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST - && safi != BGP_SAFI_VPNV4)) + && safi != SAFI_MPLS_LABELED_VPN)) { if (BGP_DEBUG (normal, NORMAL)) { @@ -1953,7 +1953,7 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size) } /* Adjust safi code. */ - if (safi == BGP_SAFI_VPNV4) + if (safi == SAFI_MPLS_LABELED_VPN) safi = SAFI_MPLS_VPN; if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 1da5d1da..7a57e13f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1660,7 +1660,7 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, u_int8_t ndata[7]; if (safi == SAFI_MPLS_VPN) - safi = BGP_SAFI_VPNV4; + safi = SAFI_MPLS_LABELED_VPN; ndata[0] = (afi >> 8); ndata[1] = afi; @@ -9088,10 +9088,8 @@ bgp_table_stats_vty (struct vty *vty, const char *name, safi = SAFI_MULTICAST; else if (strncmp (safi_str, "u", 1) == 0) safi = SAFI_UNICAST; - else if (strncmp (safi_str, "vpnv4", 5) == 0) - safi = BGP_SAFI_VPNV4; - else if (strncmp (safi_str, "vpnv6", 5) == 0) - safi = BGP_SAFI_VPNV6; + else if (strncmp (safi_str, "vpnv4", 5) == 0 || strncmp (safi_str, "vpnv6", 5) == 0) + safi = SAFI_MPLS_LABELED_VPN; else { vty_out (vty, "%% Invalid subsequent address family %s%s", @@ -9106,13 +9104,6 @@ bgp_table_stats_vty (struct vty *vty, const char *name, return CMD_WARNING; } - if ((afi == AFI_IP && safi == BGP_SAFI_VPNV6) - || (afi == AFI_IP6 && safi == BGP_SAFI_VPNV4)) - { - vty_out (vty, "%% Invalid subsequent address family %s for %s%s", - afi_str, safi_str, VTY_NEWLINE); - return CMD_WARNING; - } return bgp_table_stats (vty, bgp, afi, safi); } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 73a9ea12..759d2570 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -724,9 +724,8 @@ struct bgp_nlri #define BGP_DEFAULT_RESTART_TIME 120 #define BGP_DEFAULT_STALEPATH_TIME 360 -/* SAFI which used in open capability negotiation. */ -#define BGP_SAFI_VPNV4 128 -#define BGP_SAFI_VPNV6 128 +/* RFC4364 */ +#define SAFI_MPLS_LABELED_VPN 128 /* Max TTL value. */ #define TTL_MAX 255 diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c index 0dbf4fb9..9b43159c 100644 --- a/tests/bgp_capability_test.c +++ b/tests/bgp_capability_test.c @@ -96,10 +96,10 @@ static struct test_segment mp_segments[] = }, /* 6 */ { "MP3", - "MP IP6/VPNv4", + "MP IP6/MPLS-labeled VPN", { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 }, - 6, SHOULD_PARSE, 0, /* parses, but invalid afi,safi */ - 1, AFI_IP6, BGP_SAFI_VPNV4, INVALID_AFI, + 6, SHOULD_PARSE, 0, + 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI, }, /* 7 */ { "MP5", @@ -110,21 +110,14 @@ static struct test_segment mp_segments[] = }, /* 8 */ { "MP6", - "MP IP4/VPNv4", + "MP IP4/MPLS-laveled VPN", { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 }, 6, SHOULD_PARSE, 0, - 1, AFI_IP, BGP_SAFI_VPNV4, VALID_AFI, + 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, }, - /* 9 */ - { "MP7", - "MP IP4/VPNv6", - { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x81 }, - 6, SHOULD_PARSE, 0, /* parses, but invalid afi,safi tuple */ - 1, AFI_IP, BGP_SAFI_VPNV6, INVALID_AFI, - }, /* 10 */ { "MP8", - "MP unknown AFI", + "MP unknown AFI/SAFI", { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 }, 6, SHOULD_PARSE, 0, 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */ diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c index dde0df2f..d6e9f0ce 100644 --- a/tests/bgp_mp_attr_test.c +++ b/tests/bgp_mp_attr_test.c @@ -286,10 +286,10 @@ static struct test_segment { SHOULD_ERR, AFI_IP, SAFI_UNICAST, VALID_AFI, }, - { "IPv4-vpnv4", - "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs", + { "IPv4-MLVPN", + "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, 3 NLRIs", { - /* AFI / SAFI */ 0x0, AFI_IP, BGP_SAFI_VPNV4, + /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 1, 2, 0, 0xff, 3, 4, @@ -409,10 +409,10 @@ static struct test_segment mp_unreach_segments [] = SHOULD_ERR, AFI_IP, SAFI_UNICAST, VALID_AFI, }, - { "IPv4-unreach-vpnv4", - "IPv4/VPNv4 MP Unreach, RD, 3 NLRIs", + { "IPv4-unreach-MLVPN", + "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", { - /* AFI / SAFI */ 0x0, AFI_IP, BGP_SAFI_VPNV4, + /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, /* nexthop bytes */ 12, /* RD */ 0, 0, 1, 2, 0, 0xff, 3, 4, -- cgit v1.2.1 From 5112233b7929299b5200ef820d1567f5d7db50e6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 14 Jul 2011 16:30:08 +0400 Subject: configure: fix FreeBSD header detection (BZ#408) This change is based on Xavier Beaudouin's patch (which fixes detection of 3 config.h macros on FreeBSD without any impact to Linux build of Quagga) and FreeBSD port patch (which fixes 5 config.h macros, but breaks the Linux build), it fixes 5 macros and works for both FreeBSD 8 and Linux. --- configure.ac | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 697453cb..9e958b1c 100755 --- a/configure.ac +++ b/configure.ac @@ -443,8 +443,35 @@ m4_define([QUAGGA_INCLUDES], #endif /* TIME_WITH_SYS_TIME */ ])dnl -AC_CHECK_HEADERS([sys/un.h net/if.h netinet/in_systm.h netinet/in_var.h \ - net/if_dl.h net/if_var.h net/netopt.h net/route.h \ +dnl HAVE_NET_IF_H must be discovered by the time the longer AC_CHECK_HEADERS +dnl round below execution begins, otherwise it doesn't properly detect +dnl HAVE_NETINET6_IN6_VAR_H, HAVE_NET_IF_VAR_H and HAVE_STRUCT_IN6_ALIASREQ +dnl on FreeBSD (BZ#408). + +AC_CHECK_HEADERS([net/if.h], [], [], QUAGGA_INCLUDES) + +m4_define([QUAGGA_INCLUDES], +QUAGGA_INCLUDES +[#if HAVE_NET_IF_H +# include +#endif +])dnl + +dnl Same applies for HAVE_NET_IF_VAR_H, which HAVE_NETINET6_ND6_H and +dnl HAVE_NETINET_IN_VAR_H depend upon. But if_var.h depends on if.h, hence +dnl an additional round for it. + +AC_CHECK_HEADERS([net/if_var.h], [], [], QUAGGA_INCLUDES) + +m4_define([QUAGGA_INCLUDES], +QUAGGA_INCLUDES +[#if HAVE_NET_IF_VAR_H +# include +#endif +])dnl + +AC_CHECK_HEADERS([sys/un.h netinet/in_systm.h netinet/in_var.h \ + net/if_dl.h net/netopt.h net/route.h \ inet/nd.h arpa/inet.h netinet/ip_icmp.h \ fcntl.h stddef.h sys/ioctl.h syslog.h wchar.h wctype.h \ sys/sysctl.h sys/sockio.h kvm.h sys/conf.h], @@ -459,10 +486,7 @@ QUAGGA_INCLUDES m4_define([QUAGGA_INCLUDES], QUAGGA_INCLUDES -[#if HAVE_NET_IF_H -# include -#endif -#if HAVE_SYS_UN_H +[#if HAVE_SYS_UN_H # include #endif #if HAVE_NETINET_IN_SYSTM_H @@ -474,9 +498,6 @@ QUAGGA_INCLUDES #if HAVE_NET_IF_DL_H # include #endif -#if HAVE_NET_IF_VAR_H -# include -#endif #if HAVE_NET_NETOPT_H # include #endif -- cgit v1.2.1 From 4a1342a56c6fdb90d9af3109afa9442ff0b850d6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 15 Jul 2011 00:24:15 +0400 Subject: configure: fix OpenPAM detection --- configure.ac | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9e958b1c..4209c0b9 100755 --- a/configure.ac +++ b/configure.ac @@ -617,6 +617,13 @@ AC_SUBST(LIBREADLINE) dnl ---------- dnl PAM module +dnl +dnl Quagga detects the PAM library it is built against by checking for a +dnl functional pam_misc.h (Linux-PAM) or openpam.h (OpenPAM) header. pam_misc.h +dnl is known to #include pam_appl.h, the standard header of a PAM library, and +dnl openpam.h doesn't do that, although depends on the header too. Hence a +dnl little assistance to AC_CHECK_HEADER is necessary for the proper detection +dnl of OpenPAM. dnl ---------- if test "$with_libpam" = "yes"; then AC_CHECK_HEADER([security/pam_misc.h], @@ -630,7 +637,7 @@ if test "$with_libpam" = "yes"; then AC_DEFINE(PAM_CONV_FUNC,openpam_ttyconv,Have openpam_ttyconv) pam_conv_func="openpam_ttyconv" ], - [], QUAGGA_INCLUDES) + [], QUAGGA_INCLUDES[#include ]) if test -z "$ac_cv_header_security_pam_misc_h$ac_cv_header_security_openpam_h" ; then AC_MSG_WARN([*** pam support will not be built ***]) with_libpam="no" -- cgit v1.2.1 From fdc38db248a220dcb80ec0ba1f1981087213651d Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 17 Jul 2011 19:33:21 +0400 Subject: bgpd: rename SAFI 3 according to RFC4760 - SAFI value 3 is reserved. It was assigned by RFC 2858 for a use that was never fully implemented, so it is deprecated by this document. * zebra.h: rename macro * bgp_fsm.c: (bgp_graceful_restart_timer_expire, bgp_graceful_stale_timer_expire, bgp_stop, bgp_establish): update * bgpd.c: (peer_nsf_stop): update * bgp_open.c: (bgp_capability_vty_out): SAFI 3 isn't a recognized case any more --- bgpd/bgp_fsm.c | 8 ++++---- bgpd/bgp_open.c | 3 --- bgpd/bgpd.c | 2 +- lib/zebra.h | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 487ebddb..813e59ef 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -355,7 +355,7 @@ bgp_graceful_restart_timer_expire (struct thread *thread) /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); @@ -388,7 +388,7 @@ bgp_graceful_stale_timer_expire (struct thread *thread) /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); @@ -481,7 +481,7 @@ bgp_stop (struct peer *peer) UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) peer->nsf[afi][safi] = 0; } @@ -799,7 +799,7 @@ bgp_establish (struct peer *peer) /* graceful restart */ UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) { if (peer->afc_nego[afi][safi] && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 21c7e367..31b7369d 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -93,9 +93,6 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer) case SAFI_MULTICAST: vty_out (vty, "SAFI Multicast"); break; - case SAFI_UNICAST_MULTICAST: - vty_out (vty, "SAFI Unicast Multicast"); - break; case SAFI_MPLS_LABELED_VPN: vty_out (vty, "SAFI MPLS-labeled VPN"); break; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 882fe37c..dafbbf72 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1147,7 +1147,7 @@ peer_nsf_stop (struct peer *peer) UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) + for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) peer->nsf[afi][safi] = 0; if (peer->t_gr_restart) diff --git a/lib/zebra.h b/lib/zebra.h index 2dc84514..6d19910c 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -504,7 +504,7 @@ extern const char *zserv_command_string (unsigned int command); /* Subsequent Address Family Identifier. */ #define SAFI_UNICAST 1 #define SAFI_MULTICAST 2 -#define SAFI_UNICAST_MULTICAST 3 +#define SAFI_RESERVED_3 3 #define SAFI_MPLS_VPN 4 #define SAFI_MAX 5 -- cgit v1.2.1 From a8b79422aadf5dc821af6699e468379002cc61f9 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Wed, 23 Mar 2011 10:30:30 +0000 Subject: bgpd: Fix compile failure if IPv6 build was disabled. * bgp_route.c: ({no_,}ipv6_bgp_network_ttl_cmd) depends on ipv6_bgp_network which is HAVE_IPV6, so these should be too. (bgp_route_init) and the installs should be similarly ifdefed --- bgpd/bgp_route.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7a57e13f..cfaf1b6f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4327,6 +4327,7 @@ ALIAS_DEPRECATED (no_bgp_network_mask_natural, "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>", @@ -4342,6 +4343,7 @@ ALIAS_DEPRECATED (no_ipv6_bgp_network, "IPv6 prefix /\n" "AS-Path hopcount limit attribute\n" "AS-Pathlimit TTL, in number of AS-Path hops\n") +#endif /* HAVE_IPV6 */ /* Aggreagete address: @@ -12096,9 +12098,11 @@ bgp_route_init (void) 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 -- cgit v1.2.1 From e9e42170c63efcdb14b9389f481f2fa8fcb4092a Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 24 Jan 2010 21:41:02 +0000 Subject: lib: prefix.c nano-optimisation * lib/prefix.c: (prefix_match) nano-optimisation, let it return early without copying pointers. --- lib/prefix.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 7dc866d1..61a278ca 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -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; -- cgit v1.2.1 From 999a305c89b12b8d059f118bf01556b9a6fd62b3 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 6 Dec 2010 12:21:52 +0000 Subject: ospfd: Lower level of some common messages from info to debug * ospf_{ism,network}.c: Certain oft-repeated but trivial messages should be debug log level, not info, to avoid spamming 'terminal monitor' --- ospfd/ospf_ism.c | 8 ++++---- ospfd/ospf_network.c | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 18402836..3172587a 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); 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; } -- cgit v1.2.1 From f4ac0fee73100c6268365df31096a64443bfb93b Mon Sep 17 00:00:00 2001 From: Wataru Tanitsu Date: Fri, 10 Sep 2010 09:47:56 -0700 Subject: bgpd: Fix display of unsigned attributes * bgp_route.c: (route_vty_out*) The local prefix, metric and weight values are all stored as uint32_t. Change the format to %u so that large values are not displayed as negative integers. --- bgpd/bgp_route.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index cfaf1b6f..de1c000f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5543,12 +5543,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, " "); @@ -5608,16 +5608,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) @@ -5884,15 +5884,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"); -- cgit v1.2.1 From cd3355b83202bc109045ba1e90b6725610aa256d Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:01:17 -0800 Subject: lib: zlog should clean up its memory * log.c: (closezlog) Also free the dynamically allocated filename when a log is closed. --- lib/log.c | 3 +++ 1 file changed, 3 insertions(+) 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); } -- cgit v1.2.1 From 0e8257d21e814c46aca485d58bcfa73e06354cad Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:03:23 -0800 Subject: ospf6d: Remove obsolete code * ospf6_area.c: (ospf6_area_delete) Get rid of unused code that refers to a nonexistent function and structure member. --- ospf6d/ospf6_area.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 3c999bbc..88c4e65c 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -202,11 +202,6 @@ ospf6_area_delete (struct ospf6_area *oa) 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); -- cgit v1.2.1 From cbfbf2f07bd90f48e268907a597652af6d2e019d Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 1 Aug 2011 16:52:03 +0400 Subject: delete CVS keywords --- INSTALL.quagga.txt | 2 -- configure.ac | 1 - isisd/dict.c | 3 --- lib/command.c | 2 -- lib/log.c | 2 -- lib/log.h | 2 -- lib/memtypes.c | 2 -- lib/route_types.awk | 2 -- solaris/Makefile.am | 1 - solaris/quagga.init.in | 2 -- tests/heavy-wq.c | 2 -- watchquagga/watchquagga.c | 2 -- 12 files changed, 23 deletions(-) diff --git a/INSTALL.quagga.txt b/INSTALL.quagga.txt index f627c922..ec4e799d 100644 --- a/INSTALL.quagga.txt +++ b/INSTALL.quagga.txt @@ -1,5 +1,3 @@ -# $Id$ - -------------------------------------------------------------------------- Building and Installing Quagga from releases or snapshots: diff --git a/configure.ac b/configure.ac index 4209c0b9..a5b9dc43 100755 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,6 @@ ## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro ## Portions Copyright (c) 2003 Paul Jakma ## -## $Id$ AC_PREREQ(2.53) AC_INIT(Quagga, 0.99.17.1, [https://bugzilla.quagga.net]) diff --git a/isisd/dict.c b/isisd/dict.c index 6c3e1e7f..a78b82ac 100644 --- a/isisd/dict.c +++ b/isisd/dict.c @@ -13,9 +13,6 @@ * This source code may be translated into executable form and incorporated * into proprietary software; there is no requirement for such software to * contain a copyright notice related to this source. - * - * $Id$ - * $Name$ */ #include diff --git a/lib/command.c b/lib/command.c index 478125f2..45eb9e31 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1,6 +1,4 @@ /* - $Id$ - Command interpreter routine for virtual terminal [aka TeletYpe] Copyright (C) 1997, 98, 99 Kunihiro Ishiguro diff --git a/lib/log.c b/lib/log.c index df6e13db..8a7e5f3a 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro * diff --git a/lib/log.h b/lib/log.h index 2dd1d313..1f9a6899 100644 --- a/lib/log.h +++ b/lib/log.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Zebra logging funcions. * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro * diff --git a/lib/memtypes.c b/lib/memtypes.c index 05d93225..d0ce8c5e 100644 --- a/lib/memtypes.c +++ b/lib/memtypes.c @@ -5,8 +5,6 @@ * * The script is sensitive to the format (though not whitespace), see * the top of memtypes.awk for more details. - * - * $Id$ */ #include "zebra.h" diff --git a/lib/route_types.awk b/lib/route_types.awk index eb3d382a..6cfd5377 100644 --- a/lib/route_types.awk +++ b/lib/route_types.awk @@ -1,5 +1,3 @@ -# $Id$ -# # Scan a file of route-type definitions (see eg route_types.txt) and # generate a corresponding header file with: # diff --git a/solaris/Makefile.am b/solaris/Makefile.am index ecaf9b9b..dcee240c 100644 --- a/solaris/Makefile.am +++ b/solaris/Makefile.am @@ -1,5 +1,4 @@ # Solaris packages automake file -# $Id$ # XXX This file uses GNU make extensions. diff --git a/solaris/quagga.init.in b/solaris/quagga.init.in index 8457e990..00426241 100755 --- a/solaris/quagga.init.in +++ b/solaris/quagga.init.in @@ -20,8 +20,6 @@ # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # -# $Id$ -# # Starts/stops the given daemon SMFINCLUDE=/lib/svc/share/smf_include.sh diff --git a/tests/heavy-wq.c b/tests/heavy-wq.c index a2c609d4..e5f688c2 100644 --- a/tests/heavy-wq.c +++ b/tests/heavy-wq.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * This file is part of Quagga. * * Quagga is free software; you can redistribute it and/or modify it diff --git a/watchquagga/watchquagga.c b/watchquagga/watchquagga.c index fb628acc..b57fd3ae 100644 --- a/watchquagga/watchquagga.c +++ b/watchquagga/watchquagga.c @@ -1,6 +1,4 @@ /* - $Id$ - Monitor status of quagga daemons and restart if necessary. Copyright (C) 2004 Andrew J. Schorr -- cgit v1.2.1 From c69f91be67896e7e68adb7da4b5b9c5f6013f1a2 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 1 Aug 2011 21:59:04 +0400 Subject: lib: remove unused variable * sockopt.c (getsockopt_ifindex): "ifindex" was never used --- lib/sockopt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/sockopt.c b/lib/sockopt.c index 55c6226b..6ab97689 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -451,8 +451,6 @@ getsockopt_ipv4_ifindex (struct msghdr *msgh) int getsockopt_ifindex (int af, struct msghdr *msgh) { - int ifindex = 0; - switch (af) { case AF_INET: @@ -465,7 +463,7 @@ getsockopt_ifindex (int af, struct msghdr *msgh) #endif default: zlog_warn ("getsockopt_ifindex: unknown address family %d", af); - return (ifindex = 0); + return 0; } } -- cgit v1.2.1 From 1740f9e5906a7cb264e7741dd57a91654cb05dd0 Mon Sep 17 00:00:00 2001 From: Alexandre Chappuis Date: Tue, 2 Aug 2011 17:37:39 +0400 Subject: ospfd: remove useless RFC1583 check * ospf_route.c: Function ospf_asbr_route_cmp is called uniquely from ospf_route_cmp() when the flag OSPF_RFC1583_COMPATIBLE is not set. Therefore, the check that the flag is set doesn't make sense at all and it can consequently be removed without doing any harm. Signed-off-by: Alexandre Chappuis Signed-off-by: Roman Hoog Antink --- ospfd/ospf_route.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 267237b8..d77c7420 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -720,10 +720,6 @@ ospf_asbr_route_cmp (struct ospf *ospf, struct ospf_route *r1, r1_type = r1->path_type; r2_type = r2->path_type; - /* If RFC1583Compat flag is on -- all paths are equal. */ - if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - return 0; - /* r1/r2 itself is backbone, and it's Inter-area path. */ if (OSPF_IS_AREA_ID_BACKBONE (r1->u.std.area_id)) r1_type = OSPF_PATH_INTER_AREA; -- cgit v1.2.1 From aad356a49d6b00590b21751ea560c54f321c73c9 Mon Sep 17 00:00:00 2001 From: Christian Hammers Date: Wed, 23 Mar 2011 13:07:55 +0300 Subject: lib: fix more format warnings (#637) The following patch was also neccessary to compile. * command.c: (config_logmsg_cmd) use "%s" format spec * if.c: (connected_log) ditto --- lib/command.c | 2 +- lib/if.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/command.c b/lib/command.c index 45eb9e31..ebb50b40 100644 --- a/lib/command.c +++ b/lib/command.c @@ -3054,7 +3054,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; diff --git a/lib/if.c b/lib/if.c index e3107116..d14cfb93 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. */ -- cgit v1.2.1 From 0ddff5764f736c0a6d0d07b28bf98970624f263b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 5 Aug 2010 10:26:30 -0700 Subject: bgpd: use XCALLOC to allocate bgpd damp array * bgpd: (bgp_damp_parameter_set) The BGP reuse_index is not initialized properly. This would cause sporadic crash when disabling dampening. Use XCALLOC correctly and the right size array is initialized and no memset is needed. --- bgpd/bgp_damp.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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)); -- cgit v1.2.1 From 5c98c5a7b1d3d71ff40b477b246b859cd22ddeed Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 5 Aug 2011 18:52:52 +0400 Subject: bgpd: touch nexthop handling code bgp_nexthop_lookup_ipv6(): declare variables where they are actually used, drop no-op initialization (the field is already 0) bgp_nexthop_lookup(): ditto bgp_nexthop_check_ebgp(): rename to bgp_nexthop_onlink() bgp_nexthop_cache_changed(): rename to bgp_nexthop_cache_different() --- bgpd/bgp_nexthop.c | 30 +++++++++++++----------------- bgpd/bgp_nexthop.h | 2 +- bgpd/bgp_route.c | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 0cde665e..de303e34 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -146,7 +146,7 @@ bgp_nexthop_same (struct nexthop *next1, struct nexthop *next2) } static int -bgp_nexthop_cache_changed (struct bgp_nexthop_cache *bnc1, +bgp_nexthop_cache_different (struct bgp_nexthop_cache *bnc1, struct bgp_nexthop_cache *bnc2) { int i; @@ -171,7 +171,7 @@ bgp_nexthop_cache_changed (struct bgp_nexthop_cache *bnc1, /* If nexthop exists on connected network return 1. */ int -bgp_nexthop_check_ebgp (afi_t afi, struct attr *attr) +bgp_nexthop_onlink (afi_t afi, struct attr *attr) { struct bgp_node *rn; @@ -256,12 +256,11 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, bnc = zlookup_query_ipv6 (&attr->extra->mp_nexthop_global); if (bnc) { - struct bgp_table *old; - struct bgp_node *oldrn; - struct bgp_nexthop_cache *oldbnc; - if (changed) { + struct bgp_table *old; + struct bgp_node *oldrn; + if (bgp_nexthop_cache_table[AFI_IP6] == cache1_table[AFI_IP6]) old = cache2_table[AFI_IP6]; else @@ -270,9 +269,9 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, oldrn = bgp_node_lookup (old, &p); if (oldrn) { - oldbnc = oldrn->info; + struct bgp_nexthop_cache *oldbnc = oldrn->info; - bnc->changed = bgp_nexthop_cache_changed (bnc, oldbnc); + bnc->changed = bgp_nexthop_cache_different (bnc, oldbnc); if (bnc->metric != oldbnc->metric) bnc->metricchanged = 1; @@ -282,7 +281,6 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, else { bnc = bnc_new (); - bnc->valid = 0; } rn->info = bnc; } @@ -345,12 +343,11 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, bnc = zlookup_query (addr); if (bnc) { - struct bgp_table *old; - struct bgp_node *oldrn; - struct bgp_nexthop_cache *oldbnc; - if (changed) { + struct bgp_table *old; + struct bgp_node *oldrn; + if (bgp_nexthop_cache_table[AFI_IP] == cache1_table[AFI_IP]) old = cache2_table[AFI_IP]; else @@ -359,9 +356,9 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, oldrn = bgp_node_lookup (old, &p); if (oldrn) { - oldbnc = oldrn->info; + struct bgp_nexthop_cache *oldbnc = oldrn->info; - bnc->changed = bgp_nexthop_cache_changed (bnc, oldbnc); + bnc->changed = bgp_nexthop_cache_different (bnc, oldbnc); if (bnc->metric != oldbnc->metric) bnc->metricchanged = 1; @@ -371,7 +368,6 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, else { bnc = bnc_new (); - bnc->valid = 0; } rn->info = bnc; } @@ -458,7 +454,7 @@ bgp_scan (afi_t afi, safi_t safi) metricchanged = 0; if (peer_sort (bi->peer) == BGP_PEER_EBGP && bi->peer->ttl == 1) - valid = bgp_nexthop_check_ebgp (afi, bi->attr); + valid = bgp_nexthop_onlink (afi, bi->attr); else valid = bgp_nexthop_lookup (afi, bi->peer, bi, &changed, &metricchanged); diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index 2dad742f..874f3bba 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -54,7 +54,7 @@ extern void bgp_connected_add (struct connected *c); extern void bgp_connected_delete (struct connected *c); extern int bgp_multiaccess_check_v4 (struct in_addr, char *); extern int bgp_config_write_scan_time (struct vty *); -extern int bgp_nexthop_check_ebgp (afi_t, struct attr *); +extern int bgp_nexthop_onlink (afi_t, struct attr *); extern int bgp_nexthop_self (afi_t, struct attr *); #endif /* _QUAGGA_BGP_NEXTHOP_H */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index de1c000f..cf8e2113 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2064,7 +2064,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* If the peer is EBGP and nexthop is not on connected route, discard it. */ if (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl == 1 - && ! bgp_nexthop_check_ebgp (afi, &new_attr) + && ! bgp_nexthop_onlink (afi, &new_attr) && ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) { reason = "non-connected next-hop;"; -- cgit v1.2.1 From 5990281d4e91e40e0e3cc9149e73c887a7119415 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 5 Aug 2011 21:47:08 +0400 Subject: bgpd: add "show ip bgp scan detail" command * bgp_nexthop.c: (show_ip_bgp_scan) transform into show_ip_bgp_scan_tables(), which uses inet_ntop() and can dump nexthops on request; (show_ip_bgp_scan_detail_cmd) new function --- bgpd/bgp_nexthop.c | 59 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index de303e34..cb5a0504 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -1189,16 +1189,13 @@ ALIAS (no_bgp_scan_time, "Configure background scanner interval\n" "Scanner interval (seconds)\n") -DEFUN (show_ip_bgp_scan, - show_ip_bgp_scan_cmd, - "show ip bgp scan", - SHOW_STR - IP_STR - BGP_STR - "BGP scan status\n") +static int +show_ip_bgp_scan_tables (struct vty *vty, const char detail) { struct bgp_node *rn; struct bgp_nexthop_cache *bnc; + char buf[INET6_ADDRSTRLEN]; + u_char i; if (bgp_scan_thread) vty_out (vty, "BGP scan is running%s", VTY_NEWLINE); @@ -1211,28 +1208,37 @@ DEFUN (show_ip_bgp_scan, if ((bnc = rn->info) != NULL) { if (bnc->valid) + { vty_out (vty, " %s valid [IGP metric %d]%s", - inet_ntoa (rn->p.u.prefix4), bnc->metric, VTY_NEWLINE); + inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN), bnc->metric, VTY_NEWLINE); + if (detail) + for (i = 0; i < bnc->nexthop_num; i++) + vty_out (vty, " %s%s", inet_ntop (AF_INET, &bnc->nexthop[i].gate.ipv4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); + } else vty_out (vty, " %s invalid%s", - inet_ntoa (rn->p.u.prefix4), VTY_NEWLINE); + inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); } #ifdef HAVE_IPV6 { - char buf[BUFSIZ]; for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP6]); rn; rn = bgp_route_next (rn)) if ((bnc = rn->info) != NULL) { if (bnc->valid) + { vty_out (vty, " %s valid [IGP metric %d]%s", - inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), + inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN), bnc->metric, VTY_NEWLINE); + if (detail) + for (i = 0; i < bnc->nexthop_num; i++) + vty_out (vty, " %s%s", inet_ntop (AF_INET6, &bnc->nexthop[i].gate.ipv4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); + } else vty_out (vty, " %s invalid%s", - inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), + inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); } } @@ -1248,14 +1254,12 @@ DEFUN (show_ip_bgp_scan, #ifdef HAVE_IPV6 { - char buf[BUFSIZ]; - for (rn = bgp_table_top (bgp_connected_table[AFI_IP6]); rn; rn = bgp_route_next (rn)) if (rn->info != NULL) vty_out (vty, " %s/%d%s", - inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), + inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN), rn->p.prefixlen, VTY_NEWLINE); } @@ -1264,6 +1268,29 @@ DEFUN (show_ip_bgp_scan, return CMD_SUCCESS; } +DEFUN (show_ip_bgp_scan, + show_ip_bgp_scan_cmd, + "show ip bgp scan", + SHOW_STR + IP_STR + BGP_STR + "BGP scan status\n") +{ + return show_ip_bgp_scan_tables (vty, 0); +} + +DEFUN (show_ip_bgp_scan_detail, + show_ip_bgp_scan_detail_cmd, + "show ip bgp scan detail", + SHOW_STR + IP_STR + BGP_STR + "BGP scan status\n" + "More detailed output\n") +{ + return show_ip_bgp_scan_tables (vty, 1); +} + int bgp_config_write_scan_time (struct vty *vty) { @@ -1305,8 +1332,10 @@ bgp_scan_init (void) install_element (BGP_NODE, &no_bgp_scan_time_cmd); install_element (BGP_NODE, &no_bgp_scan_time_val_cmd); install_element (VIEW_NODE, &show_ip_bgp_scan_cmd); + install_element (VIEW_NODE, &show_ip_bgp_scan_detail_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_scan_cmd); install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd); + install_element (ENABLE_NODE, &show_ip_bgp_scan_detail_cmd); } void -- cgit v1.2.1 From 15b1d9d0b0f54b9afbfdb784d535b3761d5efde7 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 8 Aug 2011 19:36:44 +0400 Subject: bgpd: dismiss some zlookup checks bgp_nexthop_onlink(): zlookup is not used here at all bgp_nexthop_lookup_ipv6(): rely on the detection performed by "query" function (this also changes the fallback value to 0), reorder if-block bgp_nexthop_lookup(): idem --- bgpd/bgp_nexthop.c | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index cb5a0504..95369045 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -175,10 +175,6 @@ bgp_nexthop_onlink (afi_t afi, struct attr *attr) { struct bgp_node *rn; - /* If zebra is not enabled return */ - if (zlookup->sock < 0) - return 1; - /* Lookup the address is onlink or not. */ if (afi == AFI_IP) { @@ -223,14 +219,6 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, struct bgp_nexthop_cache *bnc; struct attr *attr; - /* If lookup is not enabled, return valid. */ - if (zlookup->sock < 0) - { - if (ri->extra) - ri->extra->igpmetric = 0; - return 1; - } - /* Only check IPv6 global address only nexthop. */ attr = ri->attr; @@ -253,8 +241,9 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, } else { - bnc = zlookup_query_ipv6 (&attr->extra->mp_nexthop_global); - if (bnc) + if (NULL == (bnc = zlookup_query_ipv6 (&attr->extra->mp_nexthop_global))) + bnc = bnc_new (); + else { if (changed) { @@ -278,10 +267,6 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, } } } - else - { - bnc = bnc_new (); - } rn->info = bnc; } @@ -310,14 +295,6 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, struct bgp_nexthop_cache *bnc; struct in_addr addr; - /* If lookup is not enabled, return valid. */ - if (zlookup->sock < 0) - { - if (ri->extra) - ri->extra->igpmetric = 0; - return 1; - } - #ifdef HAVE_IPV6 if (afi == AFI_IP6) return bgp_nexthop_lookup_ipv6 (peer, ri, changed, metricchanged); @@ -340,8 +317,9 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, } else { - bnc = zlookup_query (addr); - if (bnc) + if (NULL == (bnc = zlookup_query (addr))) + bnc = bnc_new (); + else { if (changed) { @@ -365,10 +343,6 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, } } } - else - { - bnc = bnc_new (); - } rn->info = bnc; } -- cgit v1.2.1 From 22aefb2270a0cd3b1ba0f309e136e0250bd0332e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 9 Aug 2011 14:42:58 +0400 Subject: bgpd: improve "show ip bgp scan detail" * bgp_nexthop.c (show_ip_bgp_scan_tables): access proper structure field in AF_INET6 case, handle ifindex NH type properly --- bgpd/bgp_nexthop.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 95369045..1a2923cc 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -1187,7 +1187,17 @@ show_ip_bgp_scan_tables (struct vty *vty, const char detail) inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN), bnc->metric, VTY_NEWLINE); if (detail) for (i = 0; i < bnc->nexthop_num; i++) - vty_out (vty, " %s%s", inet_ntop (AF_INET, &bnc->nexthop[i].gate.ipv4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); + switch (bnc->nexthop[i].type) + { + case NEXTHOP_TYPE_IPV4: + vty_out (vty, " gate %s%s", inet_ntop (AF_INET, &bnc->nexthop[i].gate.ipv4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " ifidx %u%s", bnc->nexthop[i].ifindex, VTY_NEWLINE); + break; + default: + vty_out (vty, " invalid nexthop type %u%s", bnc->nexthop[i].type, VTY_NEWLINE); + } } else vty_out (vty, " %s invalid%s", @@ -1208,7 +1218,17 @@ show_ip_bgp_scan_tables (struct vty *vty, const char detail) bnc->metric, VTY_NEWLINE); if (detail) for (i = 0; i < bnc->nexthop_num; i++) - vty_out (vty, " %s%s", inet_ntop (AF_INET6, &bnc->nexthop[i].gate.ipv4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); + switch (bnc->nexthop[i].type) + { + case NEXTHOP_TYPE_IPV6: + vty_out (vty, " gate %s%s", inet_ntop (AF_INET6, &bnc->nexthop[i].gate.ipv6, buf, INET6_ADDRSTRLEN), VTY_NEWLINE); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " ifidx %u%s", bnc->nexthop[i].ifindex, VTY_NEWLINE); + break; + default: + vty_out (vty, " invalid nexthop type %u%s", bnc->nexthop[i].type, VTY_NEWLINE); + } } else vty_out (vty, " %s invalid%s", -- cgit v1.2.1 From 9fa6be78ecbbda17be20b8d2bc4fdde915e33d7e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 19 Aug 2011 16:27:16 +0400 Subject: ospf6d: spelling --- ospf6d/ospf6_interface.c | 8 ++++---- ospf6d/ospf6_top.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 236baf17..13d69808 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -929,7 +929,7 @@ ALIAS (show_ipv6_ospf6_interface_ifname_prefix, "Display connected prefixes to advertise\n" OSPF6_ROUTE_ADDRESS_STR OSPF6_ROUTE_PREFIX_STR - "Dispaly details of the prefixes\n" + "Display details of the prefixes\n" ) ALIAS (show_ipv6_ospf6_interface_ifname_prefix, @@ -943,7 +943,7 @@ ALIAS (show_ipv6_ospf6_interface_ifname_prefix, "Display connected prefixes to advertise\n" OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR - "Dispaly details of the prefixes\n" + "Display details of the prefixes\n" ) DEFUN (show_ipv6_ospf6_interface_prefix, @@ -982,7 +982,7 @@ ALIAS (show_ipv6_ospf6_interface_prefix, "Display connected prefixes to advertise\n" OSPF6_ROUTE_ADDRESS_STR OSPF6_ROUTE_PREFIX_STR - "Dispaly details of the prefixes\n" + "Display details of the prefixes\n" ) ALIAS (show_ipv6_ospf6_interface_prefix, @@ -995,7 +995,7 @@ ALIAS (show_ipv6_ospf6_interface_prefix, "Display connected prefixes to advertise\n" OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR - "Dispaly details of the prefixes\n" + "Display details of the prefixes\n" ) diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 82370268..38f94d7b 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -591,10 +591,10 @@ ALIAS (show_ipv6_ospf6_route, IP6_STR OSPF6_STR ROUTE_STR - "Dispaly Intra-Area routes\n" - "Dispaly Inter-Area routes\n" - "Dispaly Type-1 External routes\n" - "Dispaly Type-2 External routes\n" + "Display Intra-Area routes\n" + "Display Inter-Area routes\n" + "Display Type-1 External routes\n" + "Display Type-2 External routes\n" ) DEFUN (show_ipv6_ospf6_route_type_detail, @@ -604,10 +604,10 @@ DEFUN (show_ipv6_ospf6_route_type_detail, IP6_STR OSPF6_STR ROUTE_STR - "Dispaly Intra-Area routes\n" - "Dispaly Inter-Area routes\n" - "Dispaly Type-1 External routes\n" - "Dispaly Type-2 External routes\n" + "Display Intra-Area routes\n" + "Display Inter-Area routes\n" + "Display Type-1 External routes\n" + "Display Type-2 External routes\n" "Detailed information\n" ) { -- cgit v1.2.1 From bf510e9bc06b55ae9d9c1d6ed67152b94e80977e Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Thu, 18 Aug 2011 20:22:17 +0400 Subject: lib: simplify interface of setsockopt_multicast_ipv4(). * sockopt.[ch] (setsockopt_ipv4_multicast): ifindex is now mandatory (all non-ancient OSes can use it anyway), and if_addr parameter (the address of the interface) is now gone. (setsockopt_ipv4_multicast_if): IP_MULTICAST_IF processing moved to this new function * ospf_network.c (ospf_if_add_allspfrouters, ospf_if_drop_allspfrouters, ospf_if_add_alldrouters, ospf_if_drop_alldrouters, ospf_if_ipmulticast), rip_interface.c (ipv4_multicast_join, ipv4_multicast_leave, rip_interface_new): adapt to the new interface --- lib/sockopt.c | 77 ++++++++++++++++++++++++++++++---------------------- lib/sockopt.h | 10 +++---- ospfd/ospf_network.c | 19 ++++++------- ripd/rip_interface.c | 17 ++++-------- 4 files changed, 63 insertions(+), 60 deletions(-) diff --git a/lib/sockopt.c b/lib/sockopt.c index 6ab97689..1f9f5275 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -184,7 +184,7 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh) /* * Process multicast socket options for IPv4 in an OS-dependent manner. - * Supported options are IP_MULTICAST_IF and IP_{ADD,DROP}_MEMBERSHIP. + * Supported options are IP_{ADD,DROP}_MEMBERSHIP. * * Many operating systems have a limit on the number of groups that * can be joined per socket (where each group and local address @@ -204,22 +204,18 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh) * allow leaves, or implicitly leave all groups joined to down interfaces. */ int -setsockopt_multicast_ipv4(int sock, +setsockopt_ipv4_multicast(int sock, int optname, - struct in_addr if_addr /* required */, unsigned int mcast_addr, - unsigned int ifindex /* optional: if non-zero, may be - used instead of if_addr */) + unsigned int ifindex) { #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX - /* This is better because it uses ifindex directly */ struct ip_mreqn mreqn; int ret; switch (optname) { - case IP_MULTICAST_IF: case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: memset (&mreqn, 0, sizeof(mreqn)); @@ -227,23 +223,19 @@ setsockopt_multicast_ipv4(int sock, if (mcast_addr) mreqn.imr_multiaddr.s_addr = mcast_addr; - if (ifindex) - mreqn.imr_ifindex = ifindex; - else - mreqn.imr_address = if_addr; + mreqn.imr_ifindex = ifindex; ret = setsockopt(sock, IPPROTO_IP, optname, (void *)&mreqn, sizeof(mreqn)); if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) { /* see above: handle possible problem when interface comes back up */ - char buf[2][INET_ADDRSTRLEN]; - zlog_info("setsockopt_multicast_ipv4 attempting to drop and " - "re-add (fd %d, ifaddr %s, mcast %s, ifindex %u)", + char buf[1][INET_ADDRSTRLEN]; + zlog_info("setsockopt_ipv4_multicast attempting to drop and " + "re-add (fd %d, mcast %s, ifindex %u)", sock, - inet_ntop(AF_INET, &if_addr, buf[0], sizeof(buf[0])), inet_ntop(AF_INET, &mreqn.imr_multiaddr, - buf[1], sizeof(buf[1])), ifindex); + buf[0], sizeof(buf[0])), ifindex); setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreqn, sizeof(mreqn)); ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, @@ -264,26 +256,17 @@ setsockopt_multicast_ipv4(int sock, /* #elif defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */ /* Add your favourite OS here! */ -#else /* #if OS_TYPE */ +#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) /* #if OS_TYPE */ /* standard BSD API */ struct in_addr m; struct ip_mreq mreq; int ret; -#ifdef HAVE_BSD_STRUCT_IP_MREQ_HACK - if (ifindex) - m.s_addr = htonl(ifindex); - else -#endif - m = if_addr; + m.s_addr = htonl(ifindex); switch (optname) { - case IP_MULTICAST_IF: - return setsockopt (sock, IPPROTO_IP, optname, (void *)&m, sizeof(m)); - break; - case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: memset (&mreq, 0, sizeof(mreq)); @@ -294,13 +277,12 @@ setsockopt_multicast_ipv4(int sock, if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) { /* see above: handle possible problem when interface comes back up */ - char buf[2][INET_ADDRSTRLEN]; - zlog_info("setsockopt_multicast_ipv4 attempting to drop and " - "re-add (fd %d, ifaddr %s, mcast %s, ifindex %u)", + char buf[1][INET_ADDRSTRLEN]; + zlog_info("setsockopt_ipv4_multicast attempting to drop and " + "re-add (fd %d, mcast %s, ifindex %u)", sock, - inet_ntop(AF_INET, &if_addr, buf[0], sizeof(buf[0])), inet_ntop(AF_INET, &mreq.imr_multiaddr, - buf[1], sizeof(buf[1])), ifindex); + buf[0], sizeof(buf[0])), ifindex); setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, @@ -315,10 +297,41 @@ setsockopt_multicast_ipv4(int sock, return -1; break; } +#else + #error "Unsupported multicast API" #endif /* #if OS_TYPE */ } +/* + * Set IP_MULTICAST_IF socket option in an OS-dependent manner. + */ +int +setsockopt_ipv4_multicast_if(int sock, + unsigned int ifindex) +{ + +#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX + struct ip_mreqn mreqn; + + mreqn.imr_ifindex = ifindex; + return setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreqn, sizeof(mreqn)); + + /* Example defines for another OS, boilerplate off other code in this + function */ + /* #elif defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */ + /* Add your favourite OS here! */ +#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) + struct in_addr m; + + m.s_addr = htonl(ifindex); + + return setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&m, sizeof(m)); +#else + #error "Unsupported multicast API" +#endif +} + static int setsockopt_ipv4_ifindex (int sock, int val) { diff --git a/lib/sockopt.h b/lib/sockopt.h index cb05c6fb..69309e00 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -82,13 +82,11 @@ extern int setsockopt_ipv6_multicast_loop (int, int); (((af) == AF_INET) : SOPT_SIZE_CMSG_IFINDEX_IPV4() \ ? SOPT_SIZE_CMSG_PKTINFO_IPV6()) -extern int setsockopt_multicast_ipv4(int sock, int optname, - struct in_addr if_addr - /* required: interface to join on */, +extern int setsockopt_ipv4_multicast_if(int sock, + unsigned int ifindex); +extern int setsockopt_ipv4_multicast(int sock, int optname, unsigned int mcast_addr, - unsigned int ifindex - /* optional: if non-zero, may be used - instead of if_addr */); + unsigned int ifindex); extern int setsockopt_ipv4_tos(int sock, int tos); /* Ask for, and get, ifindex, by whatever method is supported. */ diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 1e2d44e6..3e326a8c 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -52,8 +52,8 @@ ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, + htonl (OSPF_ALLSPFROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -73,8 +73,8 @@ ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p, { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, + htonl (OSPF_ALLSPFROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -94,8 +94,8 @@ ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLDROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, + htonl (OSPF_ALLDROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -115,8 +115,8 @@ ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLDROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, + htonl (OSPF_ALLDROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -151,8 +151,7 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, unsigned int ifindex) zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", top->fd, safe_strerror (errno)); - ret = setsockopt_multicast_ipv4 (top->fd, IP_MULTICAST_IF, - p->u.prefix4, 0, ifindex); + ret = setsockopt_ipv4_multicast_if (top->fd, ifindex); if (ret < 0) zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, " "ifindex %u): %s", diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index d3b55fc0..810b71c0 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -78,9 +78,8 @@ ipv4_multicast_join (int sock, { int ret; - ret = setsockopt_multicast_ipv4 (sock, + ret = setsockopt_ipv4_multicast (sock, IP_ADD_MEMBERSHIP, - ifa, group.s_addr, ifindex); @@ -100,9 +99,8 @@ ipv4_multicast_leave (int sock, { int ret; - ret = setsockopt_multicast_ipv4 (sock, + ret = setsockopt_ipv4_multicast (sock, IP_DROP_MEMBERSHIP, - ifa, group.s_addr, ifindex); @@ -138,18 +136,13 @@ rip_interface_new (void) void rip_interface_multicast_set (int sock, struct connected *connected) { - struct in_addr addr; - assert (connected != NULL); - addr = CONNECTED_ID(connected)->u.prefix4; - - if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0, - connected->ifp->ifindex) < 0) + if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0) { zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to " - "source address %s for interface %s", - sock, inet_ntoa(addr), + "ifindex %d for interface %s", + sock, connected->ifp->ifindex, connected->ifp->name); } -- cgit v1.2.1 From 9504a6ea39a68523733a8abb147da62deae061a9 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 19 Aug 2011 22:24:27 +0400 Subject: ospf6d: justify some ABR debug code * ospf6_abr.c * ospf6_abr_examin_summary(): only fill "buf" when it is used --- ospf6d/ospf6_abr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index d38ef21a..c3a63fe6 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -555,7 +555,8 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa) prefix.family = AF_INET6; prefix.prefixlen = prefix_lsa->prefix.prefix_length; ospf6_prefix_in6_addr (&prefix.u.prefix6, &prefix_lsa->prefix); - prefix2str (&prefix, buf, sizeof (buf)); + if (is_debug) + prefix2str (&prefix, buf, sizeof (buf)); table = oa->ospf6->route_table; type = OSPF6_DEST_TYPE_NETWORK; prefix_options = prefix_lsa->prefix.prefix_options; @@ -574,7 +575,8 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa) router_lsa = (struct ospf6_inter_router_lsa *) OSPF6_LSA_HEADER_END (lsa->header); ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix); - inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf)); + if (is_debug) + inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf)); table = oa->ospf6->brouter_table; type = OSPF6_DEST_TYPE_ROUTER; options[0] = router_lsa->options[0]; -- cgit v1.2.1 From 87d29037b3f390cfb9d4e9e2aef4f0b49f98d557 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Fri, 19 Aug 2011 22:25:23 +0400 Subject: lib: fix omission in the previous commit to lib/sockopt.c * sockopt.c (setsockopt_ipv4_multicast_if): fix missed line in the previous commit. --- lib/sockopt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sockopt.c b/lib/sockopt.c index 1f9f5275..6e1feece 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -313,6 +313,7 @@ setsockopt_ipv4_multicast_if(int sock, #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX struct ip_mreqn mreqn; + memset (&mreqn, 0, sizeof(mreqn)); mreqn.imr_ifindex = ifindex; return setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreqn, sizeof(mreqn)); -- cgit v1.2.1 From a44ed99c57f340a75e94e13edfb047e3f5a49539 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 20 Aug 2011 20:58:15 +0400 Subject: ospf6d: move named constants to ospf6d.h --- ospf6d/ospf6_message.c | 2 -- ospf6d/ospf6d.h | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 4db19da7..beec272b 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -227,8 +227,6 @@ ospf6_lsack_print (struct ospf6_header *oh) } /* Receive function */ -#define MSG_OK 0 -#define MSG_NG 1 static int ospf6_header_examin (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh) diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index b6f1b737..2ac6300e 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -49,6 +49,9 @@ extern struct thread_master *master; #endif /* IPV6_DROP_MEMBERSHIP */ #endif /* ! IPV6_LEAVE_GROUP */ +#define MSG_OK 0 +#define MSG_NG 1 + /* cast macro: XXX - these *must* die, ick ick. */ #define OSPF6_PROCESS(x) ((struct ospf6 *) (x)) #define OSPF6_AREA(x) ((struct ospf6_area *) (x)) -- cgit v1.2.1 From eb223062582ba463856119efa30ae1989c2a901d Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 20 Aug 2011 22:45:58 +0400 Subject: ospf6d: ospf6_lsa_cmd_init() does not exist --- ospf6d/ospf6_lsa.h | 1 - 1 file changed, 1 deletion(-) diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index fb0f27cd..c5772768 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -243,7 +243,6 @@ 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_cmd_init (void); extern int config_write_ospf6_debug_lsa (struct vty *vty); extern void install_element_ospf6_debug_lsa (void); -- cgit v1.2.1 From b62987450e4d4e0dd18a2766aff220d42174042b Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 20 Aug 2011 23:12:00 +0400 Subject: ospf6d: add missing include Two extern declarations in ospf6_abr.h are based on struct ospf6_route, which may not be available at the time ospf6_abr.h is included. This may lead to warnings after including ospf6_abr.h just for the structures defined in it. --- ospf6d/ospf6_abr.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h index 5d00c474..86d00280 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -22,6 +22,9 @@ #ifndef OSPF6_ABR_H #define OSPF6_ABR_H +/* for struct ospf6_route */ +#include "ospf6_route.h" + /* Debug option */ extern unsigned char conf_debug_ospf6_abr; #define OSPF6_DEBUG_ABR_ON() \ -- cgit v1.2.1 From 96a0a39261b5a848228f096a1a1836fa12ed3e69 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Fri, 19 Aug 2011 23:00:30 +0400 Subject: lib: futher simplification of setsockopt_ipv4_multicast() * sockopt.c (setsockopt_ipv4_multicast): check for wrong optname with assert(), rather than return an error. --- lib/sockopt.c | 108 ++++++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/lib/sockopt.c b/lib/sockopt.c index 6e1feece..8a1eec12 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -214,42 +214,31 @@ setsockopt_ipv4_multicast(int sock, struct ip_mreqn mreqn; int ret; - switch (optname) - { - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - memset (&mreqn, 0, sizeof(mreqn)); + assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); + memset (&mreqn, 0, sizeof(mreqn)); - if (mcast_addr) - mreqn.imr_multiaddr.s_addr = mcast_addr; - - mreqn.imr_ifindex = ifindex; - - ret = setsockopt(sock, IPPROTO_IP, optname, - (void *)&mreqn, sizeof(mreqn)); - if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) - { - /* see above: handle possible problem when interface comes back up */ - char buf[1][INET_ADDRSTRLEN]; - zlog_info("setsockopt_ipv4_multicast attempting to drop and " - "re-add (fd %d, mcast %s, ifindex %u)", - sock, - inet_ntop(AF_INET, &mreqn.imr_multiaddr, - buf[0], sizeof(buf[0])), ifindex); - setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, - (void *)&mreqn, sizeof(mreqn)); - ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (void *)&mreqn, sizeof(mreqn)); - } - return ret; - break; - - default: - /* Can out and give an understandable error */ - errno = EINVAL; - return -1; - break; + if (mcast_addr) + mreqn.imr_multiaddr.s_addr = mcast_addr; + + mreqn.imr_ifindex = ifindex; + + ret = setsockopt(sock, IPPROTO_IP, optname, + (void *)&mreqn, sizeof(mreqn)); + if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) + { + /* see above: handle possible problem when interface comes back up */ + char buf[1][INET_ADDRSTRLEN]; + zlog_info("setsockopt_ipv4_multicast attempting to drop and " + "re-add (fd %d, mcast %s, ifindex %u)", + sock, + inet_ntop(AF_INET, &mreqn.imr_multiaddr, + buf[0], sizeof(buf[0])), ifindex); + setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, + (void *)&mreqn, sizeof(mreqn)); + ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (void *)&mreqn, sizeof(mreqn)); } + return ret; /* Example defines for another OS, boilerplate off other code in this function, AND handle optname as per other sections for consistency !! */ @@ -263,40 +252,31 @@ setsockopt_ipv4_multicast(int sock, struct ip_mreq mreq; int ret; + assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); + m.s_addr = htonl(ifindex); - switch (optname) + memset (&mreq, 0, sizeof(mreq)); + mreq.imr_multiaddr.s_addr = mcast_addr; + mreq.imr_interface = m; + + ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq)); + if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) { - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - memset (&mreq, 0, sizeof(mreq)); - mreq.imr_multiaddr.s_addr = mcast_addr; - mreq.imr_interface = m; - - ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq)); - if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) - { - /* see above: handle possible problem when interface comes back up */ - char buf[1][INET_ADDRSTRLEN]; - zlog_info("setsockopt_ipv4_multicast attempting to drop and " - "re-add (fd %d, mcast %s, ifindex %u)", - sock, - inet_ntop(AF_INET, &mreq.imr_multiaddr, - buf[0], sizeof(buf[0])), ifindex); - setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, - (void *)&mreq, sizeof(mreq)); - ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (void *)&mreq, sizeof(mreq)); - } - return ret; - break; - - default: - /* Can out and give an understandable error */ - errno = EINVAL; - return -1; - break; + /* see above: handle possible problem when interface comes back up */ + char buf[1][INET_ADDRSTRLEN]; + zlog_info("setsockopt_ipv4_multicast attempting to drop and " + "re-add (fd %d, mcast %s, ifindex %u)", + sock, + inet_ntop(AF_INET, &mreq.imr_multiaddr, + buf[0], sizeof(buf[0])), ifindex); + setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, + (void *)&mreq, sizeof(mreq)); + ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (void *)&mreq, sizeof(mreq)); } + return ret; + #else #error "Unsupported multicast API" #endif /* #if OS_TYPE */ -- cgit v1.2.1 From d6af701250915fdc7449500d9191f4eb2e6cfa4d Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Mon, 22 Aug 2011 11:39:35 +0400 Subject: lib: use "protocol-independed API" from RFC3678, if that is available (This commit is based on the patch from BZ#420, and should fix that bug.) * configure.ac: detect availability of that API * sockopt.c (setsockopt_ipv4_multicast): use it for join/leave IPv4 multicast groups --- configure.ac | 9 +++++++++ lib/sockopt.c | 26 ++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index a5b9dc43..40e31f25 100755 --- a/configure.ac +++ b/configure.ac @@ -944,6 +944,15 @@ 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)) +AC_MSG_CHECKING([for RFC3678 protocol-independed API]) +AC_TRY_COMPILE([ +#include +#include +], [struct group_req gr; int sock; setsockopt(sock, IPPROTO_IP, MCAST_JOIN_GROUP, (void*)&gr, sizeof(gr)); +], [AC_MSG_RESULT(yes) +AC_DEFINE(HAVE_RFC3678,1,[Have RFC3678 protocol-independed API])], +AC_MSG_RESULT(no)) + dnl --------------------------------------------------------------- dnl figure out how to check link-state dnl --------------------------------------------------------------- diff --git a/lib/sockopt.c b/lib/sockopt.c index 8a1eec12..9ff15ca6 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -209,17 +209,35 @@ setsockopt_ipv4_multicast(int sock, unsigned int mcast_addr, unsigned int ifindex) { +#ifdef HAVE_RFC3678 + struct group_req gr; + struct sockaddr_in *si; + int ret; + memset (&gr, 0, sizeof(gr)); + si = (struct sockaddr_in *)&gr.gr_group; + gr.gr_interface = ifindex; + si->sin_family = AF_INET; +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + si->sin_len = sizeof(struct sockaddr_in); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + si->sin_addr.s_addr = mcast_addr; + ret = setsockopt(sock, IPPROTO_IP, (optname == IP_ADD_MEMBERSHIP) ? + MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr)); + if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) + { + setsockopt(sock, IPPROTO_IP, MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr)); + ret = setsockopt(sock, IPPROTO_IP, MCAST_JOIN_GROUP, (void *)&gr, sizeof(gr)); + } + return ret; -#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX +#elif defined(HAVE_STRUCT_IP_MREQN_IMR_IFINDEX) && !defined(__FreeBSD__) struct ip_mreqn mreqn; int ret; assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); memset (&mreqn, 0, sizeof(mreqn)); - if (mcast_addr) - mreqn.imr_multiaddr.s_addr = mcast_addr; - + mreqn.imr_multiaddr.s_addr = mcast_addr; mreqn.imr_ifindex = ifindex; ret = setsockopt(sock, IPPROTO_IP, optname, -- cgit v1.2.1 From 68aa0c58717b3f2648533b54fb4ec689fd2d7c5c Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 23 Aug 2011 11:36:27 +0400 Subject: ospfd: sizing macros cleanup * ospf_spf.c * ROUTER_LSA_TOS_SIZE: prepend OSPF_ and move to ospf_lsa.h * ROUTER_LSA_MIN_SIZE: replace with existing OSPF_ROUTER_LSA_LINK_SIZE --- ospfd/ospf_lsa.h | 1 + ospfd/ospf_spf.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 251d4731..e51f7e8e 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -49,6 +49,7 @@ #define OSPF_LSA_HEADER_SIZE 20U #define OSPF_ROUTER_LSA_LINK_SIZE 12U +#define OSPF_ROUTER_LSA_TOS_SIZE 4U #define OSPF_MAX_LSA_SIZE 1500U /* AS-external-LSA refresh method. */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index ca200222..6dcf0b18 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -356,9 +356,6 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v) return -1; } -#define ROUTER_LSA_MIN_SIZE 12 -#define ROUTER_LSA_TOS_SIZE 4 - /* Find the next link after prev_link from v to w. If prev_link is * NULL, return the first link from v to w. Ignore stub and virtual links; * these link types will never be returned. @@ -380,8 +377,8 @@ ospf_get_next_link (struct vertex *v, struct vertex *w, else { p = (u_char *) prev_link; - p += (ROUTER_LSA_MIN_SIZE + - (prev_link->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (prev_link->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); } lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); @@ -390,7 +387,7 @@ ospf_get_next_link (struct vertex *v, struct vertex *w, { l = (struct router_lsa_link *) p; - p += (ROUTER_LSA_MIN_SIZE + (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); if (l->m[0].type != lsa_type) continue; @@ -755,8 +752,8 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area, { l = (struct router_lsa_link *) p; - p += (ROUTER_LSA_MIN_SIZE + - (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); /* (a) If this is a link to a stub network, examine the next link in V's LSA. Links to stub networks will be @@ -989,8 +986,8 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v, { l = (struct router_lsa_link *) p; - p += (ROUTER_LSA_MIN_SIZE + - (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); if (l->m[0].type == LSA_LINK_TYPE_STUB) ospf_intra_add_stub (rt, l, v, area, parent_is_root); -- cgit v1.2.1 From 330835409fb82522082eba4d4819467e5ab2de84 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 27 Aug 2011 22:19:34 +0400 Subject: ospf6d: address more trivial compiler warnings * ospf6_main.c: include required headers * ospf6_asbr.h: idem * ospf6_spf.c * ospf6_spf_install(): remove unused variables --- ospf6d/ospf6_asbr.h | 7 +++++++ ospf6d/ospf6_main.c | 5 +++++ ospf6d/ospf6_spf.c | 3 +-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 7166aa3e..72644dfc 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -22,6 +22,13 @@ #ifndef OSPF6_ASBR_H #define OSPF6_ASBR_H +/* for struct ospf6_prefix */ +#include "ospf6_proto.h" +/* for struct ospf6_lsa */ +#include "ospf6_lsa.h" +/* for struct ospf6_route */ +#include "ospf6_route.h" + /* Debug option */ extern unsigned char conf_debug_ospf6_asbr; #define OSPF6_DEBUG_ASBR_ON() \ diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index a7a96a1f..ced2ef2a 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -34,8 +34,13 @@ #include "plist.h" #include "privs.h" #include "sigevent.h" +#include "zclient.h" #include "ospf6d.h" +#include "ospf6_top.h" +#include "ospf6_message.h" +#include "ospf6_asbr.h" +#include "ospf6_lsa.h" /* Default configuration file name for ospf6d. */ #define OSPF6_DEFAULT_CONFIG "ospf6d.conf" diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 04367f08..e78f7f6a 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -282,8 +282,7 @@ ospf6_spf_install (struct ospf6_vertex *v, { struct ospf6_route *route; int i, j; - struct ospf6_vertex *prev, *w; - struct listnode *node, *nnode; + struct ospf6_vertex *prev; if (IS_OSPF6_DEBUG_SPF (PROCESS)) zlog_debug ("SPF install %s hops %d cost %d", -- cgit v1.2.1 From 695421486d651816a7082447adf2fec9fea50930 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 28 Aug 2011 22:29:52 +0400 Subject: zebra: add missing includes --- zebra/if_netlink.c | 2 ++ zebra/rtread_netlink.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 701c81b6..86bd8ffe 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -22,6 +22,8 @@ #include +#include "zebra/zserv.h" + extern int interface_lookup_netlink (void); /* Interface information read by netlink. */ diff --git a/zebra/rtread_netlink.c b/zebra/rtread_netlink.c index 44715d94..066e8443 100644 --- a/zebra/rtread_netlink.c +++ b/zebra/rtread_netlink.c @@ -21,6 +21,9 @@ */ #include + +#include "zebra/zserv.h" + extern void netlink_route_read (void); void route_read (void) -- cgit v1.2.1 From 84f6c0d6cecd039b5dc529b6c5eba136840a4010 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 28 Aug 2011 22:38:45 +0400 Subject: ospfd: address more trivial compiler warnings * ospf_ase.c * ospf_ase_complete_direct_routes(): dismiss unused variable * ospf_ase_calculate_route(): put assignments into parentheses --- ospfd/ospf_ase.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 5d0cae42..7b7a798a 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -135,7 +135,6 @@ ospf_ase_complete_direct_routes (struct ospf_route *ro, struct in_addr nexthop) { struct listnode *node; struct ospf_path *op; - struct interface *ifp; for (ALL_LIST_ELEMENTS_RO (ro->paths, node, op)) if (op->nexthop.s_addr == 0) @@ -451,8 +450,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 (NULL != (rn = route_node_lookup (ospf->new_table, + (struct prefix *) &p))) { route_unlock_node(rn); if (rn->info == NULL) @@ -463,8 +462,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 (NULL != (rn = route_node_lookup (ospf->new_external_route, + (struct prefix *) &p))) route_unlock_node(rn); if (!rn || (or = rn->info) == NULL) -- cgit v1.2.1 From 68575f4babf4d6fc302c366898a1047f13629214 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Sat, 3 Sep 2011 14:35:24 +0400 Subject: build: build ospfd as Position-Independed Executable (if appropriate) Since 46bc0e432e75, all the binaries are built as Position-Independed Executables (if available and enabled). ospfd was missed for some unknown reason. --- ospfd/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ospfd/Makefile.am b/ospfd/Makefile.am index 2e4d5c8e..390f2e3f 100644 --- a/ospfd/Makefile.am +++ b/ospfd/Makefile.am @@ -4,6 +4,9 @@ INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib @SNMP_INCLUDES@ DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" INSTALL_SDATA=@INSTALL@ -m 600 +AM_CFLAGS = $(PICFLAGS) +AM_LDFLAGS = $(PILDFLAGS) + lib_LTLIBRARIES = libospf.la libospf_la_LDFLAGS = -version 0:0:0 -- cgit v1.2.1 From c66caa83f96cd11c95c05b40da9ed8064e236005 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 7 Sep 2011 15:40:06 +0400 Subject: version RE-0.99.17.2 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 40e31f25..1205e8cc 100755 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.17.1, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.17.2, [https://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) -- cgit v1.2.1 From 6caee4c9cdcf72e603b1ebd70f209ccdc75f0b95 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 7 Sep 2011 17:40:38 +0400 Subject: ospfd: revert recent PIE change to fix amd64 build This reverts commit 68575f4babf4d6fc302c366898a1047f13629214. --- ospfd/Makefile.am | 3 --- 1 file changed, 3 deletions(-) diff --git a/ospfd/Makefile.am b/ospfd/Makefile.am index 390f2e3f..2e4d5c8e 100644 --- a/ospfd/Makefile.am +++ b/ospfd/Makefile.am @@ -4,9 +4,6 @@ INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib @SNMP_INCLUDES@ DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" INSTALL_SDATA=@INSTALL@ -m 600 -AM_CFLAGS = $(PICFLAGS) -AM_LDFLAGS = $(PILDFLAGS) - lib_LTLIBRARIES = libospf.la libospf_la_LDFLAGS = -version 0:0:0 -- cgit v1.2.1 From 2f7d5fb38a284a00f990f943fbd3fbd8961ef52e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 7 Sep 2011 17:44:10 +0400 Subject: version RE-0.99.17.3 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1205e8cc..adcd8d2d 100755 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.17.2, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.17.3, [https://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) -- cgit v1.2.1 From 4f151e5cc6ac6cfb1042dc3e5a1139a9f3138d91 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 10 Sep 2011 16:40:23 +0400 Subject: ospfd: use existing macro for consistency --- ospfd/ospf_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index adc822a7..955a8227 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -7896,9 +7896,9 @@ config_write_ospf_distribute (struct vty *vty, struct ospf *ospf) { /* distribute-list print. */ for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - if (ospf->dlist[type].name) + if (DISTRIBUTE_NAME (ospf, type)) vty_out (vty, " distribute-list %s out %s%s", - ospf->dlist[type].name, + DISTRIBUTE_NAME (ospf, type), zebra_route_string(type), VTY_NEWLINE); /* default-information print. */ -- cgit v1.2.1 From 71008de7c8d47e5163d103b0b509d4a899044014 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 10 Sep 2011 16:53:30 +0400 Subject: bgpd: spelling --- bgpd/bgp_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 6c170ab6..1ed23285 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -908,7 +908,7 @@ bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, peer->last_reset = PEER_DOWN_NOTIFY_SEND; } - /* Call imidiately. */ + /* Call immediately. */ BGP_WRITE_OFF (peer->t_write); bgp_write_notify (peer); -- cgit v1.2.1 From 6787978cc8c15b16fff3e6d6e09e02518dc045f2 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 10 Sep 2011 21:50:53 +0400 Subject: bgpd: spelling --- bgpd/bgp_vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index ec0106a8..6dd49a06 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3705,7 +3705,7 @@ peer_maximum_prefix_set_vty (struct vty *vty, const char *ip_str, afi_t afi, if (! peer) return CMD_WARNING; - VTY_GET_INTEGER ("maxmum number", max, num_str); + VTY_GET_INTEGER ("maximum number", max, num_str); if (threshold_str) threshold = atoi (threshold_str); else -- cgit v1.2.1 From e00d4e2e3dd20d567d670cae1c33618910c639fa Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 10 Sep 2011 23:29:19 +0400 Subject: ospfd: spelling --- ospfd/ospf_zebra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 50ca85e1..bffa90db 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -670,7 +670,7 @@ ospf_external_lsa_originate_check (struct ospf *ospf, if (is_prefix_default (&ei->p)) if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) { - zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA " + zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA " "for default"); return 0; } -- cgit v1.2.1 From 257c0eb350f314014ff1f8a993f3cf2456964cda Mon Sep 17 00:00:00 2001 From: Dmitry Popov Date: Sun, 11 Sep 2011 13:48:25 +0400 Subject: zebra: fix loss of metric for Linux routes * rt_netlink.c * netlink_route_change(): fetch metric information like netlink_routing_table() does and pass it further --- zebra/rt_netlink.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 7652f80a..eb9eae3a 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -768,6 +768,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) int index; int table; + int metric; + void *dest; void *gate; void *src; @@ -825,6 +827,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) } index = 0; + metric = 0; dest = NULL; gate = NULL; src = NULL; @@ -843,6 +846,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) if (tb[RTA_PREFSRC]) src = RTA_DATA (tb[RTA_PREFSRC]); + if (h->nlmsg_type == RTM_NEWROUTE && tb[RTA_PRIORITY]) + metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]); + if (rtm->rtm_family == AF_INET) { struct prefix_ipv4 p; @@ -861,7 +867,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) } if (h->nlmsg_type == RTM_NEWROUTE) - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0); + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, metric, 0); else rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table); } @@ -889,7 +895,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) } if (h->nlmsg_type == RTM_NEWROUTE) - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0); + rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, metric, 0); else rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table); } -- cgit v1.2.1 From 99dc8691caa8bd1eaf4d5784bdb72a10966f2007 Mon Sep 17 00:00:00 2001 From: Alexandre Chappuis Date: Sun, 11 Sep 2011 16:54:11 +0400 Subject: doc: BGP route-flap dampening --- doc/bgpd.texi | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/bgpd.texi b/doc/bgpd.texi index e7463300..63834600 100644 --- a/doc/bgpd.texi +++ b/doc/bgpd.texi @@ -85,6 +85,7 @@ so @code{router-id} is set to 0.0.0.0. So please set router-id by hand. @menu * BGP distance:: * BGP decision process:: +* BGP route flap dampening:: @end menu @node BGP distance @@ -123,6 +124,27 @@ sequences should should be taken into account during the BGP best path decision process. @end deffn +@node BGP route flap dampening +@subsection BGP route flap dampening + +@deffn {BGP} {bgp dampening @var{<1-45>} @var{<1-20000>} @var{<1-20000>} @var{<1-255>}} {} +This command enables BGP route-flap dampening and specifies dampening parameters. + +@table @asis +@item @asis{half-life} +Half-life time for the penalty +@item @asis{reuse-threshold} +Value to start reusing a route +@item @asis{suppress-threshold} +Value to start suppressing a route +@item @asis{max-suppress} +Maximum duration to suppress a stable route +@end table + +The route-flap damping algorithm is compatible with @cite{RFC2439}. The use of this command +is not recommended nowadays, see @uref{http://www.ripe.net/ripe/docs/ripe-378,,RIPE-378}. +@end deffn + @node BGP network @section BGP network @@ -930,6 +952,14 @@ Clear peers which have addresses of X.X.X.X Clear peer using soft reconfiguration. @end deffn +@deffn {Command} {show ip bgp dampened-paths} {} +Display paths suppressed due to dampening +@end deffn + +@deffn {Command} {show ip bgp flap-statistics} {} +Display flap statistics of routes +@end deffn + @deffn {Command} {show debug} {} @end deffn -- cgit v1.2.1 From 2e35e96a11ac7bdf82ad68056f94135dc41a0995 Mon Sep 17 00:00:00 2001 From: heasley Date: Mon, 12 Sep 2011 13:27:52 +0400 Subject: bgpd: add useful notification logs (BZ#616) * bgp_packet.c * bgp_notify_send_with_data(): add calls to zlog_info() --- bgpd/bgp_packet.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 1ed23285..5f150600 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -901,12 +901,25 @@ bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE) { if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET) - peer->last_reset = PEER_DOWN_USER_RESET; + { + peer->last_reset = PEER_DOWN_USER_RESET; + zlog_info ("Notification sent to neighbor %s: User reset", peer->host); + } else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN) - peer->last_reset = PEER_DOWN_USER_SHUTDOWN; + { + peer->last_reset = PEER_DOWN_USER_SHUTDOWN; + zlog_info ("Notification sent to neighbor %s: shutdown", peer->host); + } else - peer->last_reset = PEER_DOWN_NOTIFY_SEND; + { + peer->last_reset = PEER_DOWN_NOTIFY_SEND; + zlog_info ("Notification sent to neighbor %s: type %u/%u", + peer->host, code, sub_code); + } } + else + zlog_info ("Notification sent to neighbor %s: configuration change", + peer->host); /* Call immediately. */ BGP_WRITE_OFF (peer->t_write); -- cgit v1.2.1 From c8049c165cdab08cb8024881376080b58ebc9eae Mon Sep 17 00:00:00 2001 From: Christian Hammers Date: Mon, 12 Sep 2011 14:23:05 +0400 Subject: ospf6d: fix crash on filter-list handling (BZ#530) This essentially merges the fix available from Debian build of Quagga. * ospf6_area.c * area_filter_list(): use correct argv indices * no_area_filter_list(): idem --- ospf6d/ospf6_area.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 88c4e65c..d73d996b 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -440,14 +440,14 @@ DEFUN (area_filter_list, argc--; argv++; - plist = prefix_list_lookup (AFI_IP6, argv[1]); - if (strncmp (argv[2], "in", 2) == 0) + plist = prefix_list_lookup (AFI_IP6, argv[0]); + if (strncmp (argv[1], "in", 2) == 0) { PREFIX_LIST_IN (area) = plist; if (PREFIX_NAME_IN (area)) free (PREFIX_NAME_IN (area)); - PREFIX_NAME_IN (area) = strdup (argv[1]); + PREFIX_NAME_IN (area) = strdup (argv[0]); ospf6_abr_reimport (area); } else @@ -456,7 +456,7 @@ DEFUN (area_filter_list, if (PREFIX_NAME_OUT (area)) free (PREFIX_NAME_OUT (area)); - PREFIX_NAME_OUT (area) = strdup (argv[1]); + PREFIX_NAME_OUT (area) = strdup (argv[0]); ospf6_abr_enable_area (area); } @@ -482,11 +482,11 @@ DEFUN (no_area_filter_list, argc--; argv++; - plist = prefix_list_lookup (AFI_IP6, argv[1]); - if (strncmp (argv[2], "in", 2) == 0) + plist = prefix_list_lookup (AFI_IP6, argv[0]); + if (strncmp (argv[1], "in", 2) == 0) { if (PREFIX_NAME_IN (area)) - if (strcmp (PREFIX_NAME_IN (area), argv[1]) != 0) + if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0) return CMD_SUCCESS; PREFIX_LIST_IN (area) = NULL; @@ -499,7 +499,7 @@ DEFUN (no_area_filter_list, else { if (PREFIX_NAME_OUT (area)) - if (strcmp (PREFIX_NAME_OUT (area), argv[1]) != 0) + if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0) return CMD_SUCCESS; PREFIX_LIST_OUT (area) = NULL; -- cgit v1.2.1 From 74ffab30c360e2a603247f574577b3a8a74db4b2 Mon Sep 17 00:00:00 2001 From: Peter Pentchev Date: Mon, 12 Sep 2011 16:30:31 +0400 Subject: bgpd: fix parsing of graceful restart cap. (#663) "While setting up a testbed, I ran across a little problem in the parsing of the "graceful restart" BGP capability that resulted in Quagga not actually activating it for the peer in question - when the peer sent a single AFI/SAFI block." * bgp_open.c * bgp_capability_restart(): actually process the last AFI/SAFI block --- bgpd/bgp_open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 31b7369d..82deb3d0 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -380,7 +380,7 @@ bgp_capability_restart (struct peer *peer, struct capability_header *caphdr) peer->v_gr_restart); } - while (stream_get_getp (s) + 4 < end) + while (stream_get_getp (s) + 4 <= end) { afi_t afi = stream_getw (s); safi_t safi = stream_getc (s); -- cgit v1.2.1 From 4fe20b3f7d13252348e7efaedbaa8f10456cfd52 Mon Sep 17 00:00:00 2001 From: Jon Andersson Date: Tue, 13 Sep 2011 15:47:14 +0400 Subject: ospf6d: add lost lines to area config block * ospf6_area.c * ospf6_area_config_write(): write filter-list, import-list and export-list lines --- ospf6d/ospf6_area.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index d73d996b..0224fe68 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -419,6 +419,18 @@ ospf6_area_config_write (struct vty *vty) prefix2str (&range->prefix, buf, sizeof (buf)); vty_out (vty, " area %s range %s%s", oa->name, buf, VNL); } + if (PREFIX_NAME_IN (oa)) + vty_out (vty, " area %s filter-list prefix %s in%s", + oa->name, PREFIX_NAME_IN (oa), VNL); + if (PREFIX_NAME_OUT (oa)) + vty_out (vty, " area %s filter-list prefix %s out%s", + oa->name, PREFIX_NAME_OUT (oa), VNL); + if (IMPORT_NAME (oa)) + vty_out (vty, " area %s import-list %s%s", + oa->name, IMPORT_NAME (oa), VNL); + if (EXPORT_NAME (oa)) + vty_out (vty, " area %s export-list %s%s", + oa->name, EXPORT_NAME (oa), VNL); } } -- cgit v1.2.1 From b38639ca49e2d0348bdc774f987a8f2f9d2ede74 Mon Sep 17 00:00:00 2001 From: Alexandre Chappuis Date: Tue, 13 Sep 2011 16:33:45 +0400 Subject: doc: add missing word * ospfd.texi: Adjust meaning of the rfc1583compatibility option in order to match the RFC specification and the actual source code. --- doc/ospfd.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ospfd.texi b/doc/ospfd.texi index f879a986..0a085db4 100644 --- a/doc/ospfd.texi +++ b/doc/ospfd.texi @@ -99,7 +99,7 @@ behaviors implemented in Cisco and IBM routers." to section G.2 (changes) in section 16.4 a change to the path preference algorithm that prevents possible routing loops that were possible in the old version of OSPFv2. More specifically it demands -that inter-area paths and intra-area path are now of equal preference +that inter-area paths and intra-area backbone path are now of equal preference but still both preferred to external paths. This command should NOT be set normally. -- cgit v1.2.1 From 3f0d3a1f9c7b7f751473d9293ba2272a28e2a8f2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 13 Sep 2011 17:15:51 +0400 Subject: configure: dismiss libutil.h Recent versions of libc on Linux (Debian Testing) create lots of compile warnings about direct usage of libutil.h --- configure.ac | 2 +- lib/zebra.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index adcd8d2d..75f99a64 100755 --- a/configure.ac +++ b/configure.ac @@ -395,7 +395,7 @@ dnl Check other header files. dnl ------------------------- AC_CHECK_HEADERS([stropts.h sys/ksym.h sys/times.h sys/select.h \ sys/types.h linux/version.h netdb.h asm/types.h \ - sys/param.h limits.h signal.h libutil.h \ + sys/param.h limits.h signal.h \ sys/socket.h netinet/in.h time.h sys/time.h]) dnl Utility macro to avoid retyping includes all the time diff --git a/lib/zebra.h b/lib/zebra.h index 6d19910c..c4c69d3d 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -237,10 +237,6 @@ typedef int socklen_t; #define UINT32_MAX (4294967295U) #endif -#ifdef HAVE_LIBUTIL_H -#include -#endif /* HAVE_LIBUTIL_H */ - #ifdef HAVE_GLIBC_BACKTRACE #include #endif /* HAVE_GLIBC_BACKTRACE */ -- cgit v1.2.1 From a7c21ecd6df936b2f6614956ef9167b5fcc165c8 Mon Sep 17 00:00:00 2001 From: Peter Szilagyi Date: Tue, 13 Sep 2011 17:37:06 +0400 Subject: isisd: include hash.h, not hash.c --- isisd/isis_pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index a2ab0649..8219e837 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -29,7 +29,7 @@ #include "log.h" #include "stream.h" #include "vty.h" -#include "hash.c" +#include "hash.h" #include "prefix.h" #include "if.h" #include "checksum.h" -- cgit v1.2.1 From f7c91fc330b802e95e23d52b498ae61b0e8669a9 Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:02:11 -0800 Subject: ospf6d: Extend the "[no] debug ospf6 route" vty commands * ospf6_route.c ([no_]debug_ospf6_route) Include memory as a debug option. This allows ospf6 route memory debugging to be enabled or disabled interactively or from a config file. --- ospf6d/ospf6_route.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 1e1f4fb5..2d027101 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -1335,13 +1335,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 +1353,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 +1377,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; } -- cgit v1.2.1 From 158dd4d00ecb0af0d1a77fdc7d4844fc88a0f10f Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:02:38 -0800 Subject: ospf6d: Fix memory allocation issues in SPF * ospf6_area.c: Call ospf6_spf_table_finish() before deleting the spf table. This ensures that the associated ospf6_vertex structures are also freed. * ospf6_spf.c: Only allocate a priority queue when a spf calculation is actually performed. --- ospf6d/ospf6_area.c | 1 + ospf6d/ospf6_spf.c | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 0224fe68..9934e6b9 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -199,6 +199,7 @@ 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); diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index e78f7f6a..a4a5b721 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -391,10 +391,6 @@ 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 */ @@ -403,6 +399,11 @@ ospf6_spf_calculation (u_int32_t router_id, router_id, oa->lsdb); if (lsa == NULL) return; + + /* initialize */ + candidate_list = pqueue_create (); + candidate_list->cmp = ospf6_vertex_cmp; + root = ospf6_vertex_create (lsa); root->area = oa; root->cost = 0; -- cgit v1.2.1 From d0d29979d05ddc532475b595b32041412de523c7 Mon Sep 17 00:00:00 2001 From: Fritz Reichmann Date: Wed, 14 Sep 2011 19:31:51 +0400 Subject: isisd: fix crash on "no router isis" (BZ#536) The crash is due to threads accessing data that gets destroyed during the removal of the configuration. * isis_circuit.c: Destroy adjacencies to stop adjacency expiry thread. Stop PSNP threads. * isisd.c: Change state of circuit back to INIT and reassign the circuit structure to isis->init_circ_list rather than destroying the circuit data structure. Stop SPF threads. Stop LSP generation threads. * isisd.h: Add pointers to LSP threads into area structure in order to stop them in isisd.c * isis_lsp.c: Store pointer to LSP thread in area structure. * isis_pdu.c: Stop PDU generation for a circuit with a removed area. * isis_pfpacket.c: Stop processing received PDUs for a circuit with a removed area. --- isisd/isis_circuit.c | 12 ++++++++++++ isisd/isis_lsp.c | 4 ++-- isisd/isis_pdu.c | 8 ++++++++ isisd/isis_pfpacket.c | 4 ++++ isisd/isisd.c | 13 ++++++++++++- isisd/isisd.h | 2 ++ 6 files changed, 40 insertions(+), 3 deletions(-) diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index d2923b57..e34d491a 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -142,6 +142,11 @@ isis_circuit_deconfigure (struct isis_circuit *circuit, struct isis_area *area) { + /* destroy adjacencies */ + if (circuit->u.bc.adjdb[0]) + isis_adjdb_iterate (circuit->u.bc.adjdb[0], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[0]); + if (circuit->u.bc.adjdb[1]) + isis_adjdb_iterate (circuit->u.bc.adjdb[1], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[1]); /* Remove circuit from area */ listnode_delete (area->circuit_list, circuit); /* Free the index of SRM and SSN flags */ @@ -602,6 +607,13 @@ isis_circuit_down (struct isis_circuit *circuit) { THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello); } + + if (circuit->t_send_psnp[0]) { + THREAD_TIMER_OFF (circuit->t_send_psnp[0]); + } + if (circuit->t_send_psnp[1]) { + THREAD_TIMER_OFF (circuit->t_send_psnp[1]); + } /* close the socket */ close (circuit->fd); diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 50289db3..e12e4ca8 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -1640,7 +1640,7 @@ lsp_regenerate_schedule (struct isis_area *area) if (diff < MIN_LSP_GEN_INTERVAL) { area->lsp_regenerate_pending[0] = 1; - thread_add_timer (master, lsp_l1_regenerate, area, + area->t_lsp_l1_regenerate=thread_add_timer (master, lsp_l1_regenerate, area, MIN_LSP_GEN_INTERVAL - diff); goto L2; } @@ -1663,7 +1663,7 @@ L2: if (diff < MIN_LSP_GEN_INTERVAL) { area->lsp_regenerate_pending[1] = 1; - thread_add_timer (master, lsp_l2_regenerate, area, + area->t_lsp_l2_regenerate=thread_add_timer (master, lsp_l2_regenerate, area, MIN_LSP_GEN_INTERVAL - diff); return ISIS_OK; } diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 8219e837..34e4b03d 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1781,6 +1781,9 @@ isis_receive (struct thread *thread) circuit = THREAD_ARG (thread); assert (circuit); + if (!circuit->area) + return ISIS_OK; + if (circuit->rcv_stream == NULL) circuit->rcv_stream = stream_new (ISO_MTU (circuit)); else @@ -2088,6 +2091,11 @@ send_lan_l2_hello (struct thread *thread) circuit = THREAD_ARG (thread); assert (circuit); + + if (!circuit->area) { + return ISIS_OK; + } + circuit->u.bc.t_send_lan_hello[1] = NULL; if (circuit->u.bc.run_dr_elect[1]) diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c index 9e4165e3..8a5c3ed0 100644 --- a/isisd/isis_pfpacket.c +++ b/isisd/isis_pfpacket.c @@ -232,6 +232,10 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa) LLC_LEN, MSG_PEEK, (struct sockaddr *) &s_addr, (socklen_t *) &addr_len); + if (!circuit->area) { + return ISIS_OK; + } + if (bytesread < 0) { zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s", diff --git a/isisd/isisd.c b/isisd/isisd.c index 1e84a1ce..20a32809 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -52,6 +52,7 @@ #include "isisd/isis_route.h" #include "isisd/isis_zebra.h" #include "isisd/isis_events.h" +#include "isisd/isis_csm.h" #ifdef TOPOLOGY_GENERATE #include "spgrid.h" @@ -217,21 +218,31 @@ isis_area_destroy (struct vty *vty, const char *area_tag) for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit)) { /* The fact that it's in circuit_list means that it was configured */ + isis_csm_state_change (ISIS_DISABLE, circuit, area); + isis_circuit_down (circuit); isis_circuit_deconfigure (circuit, area); - isis_circuit_del (circuit); } list_delete (area->circuit_list); } listnode_delete (isis->area_list, area); + THREAD_TIMER_OFF (area->t_tick); if (area->t_remove_aged) thread_cancel (area->t_remove_aged); THREAD_TIMER_OFF (area->t_lsp_refresh[0]); THREAD_TIMER_OFF (area->t_lsp_refresh[1]); + THREAD_TIMER_OFF (area->spftree[0]->t_spf); + THREAD_TIMER_OFF (area->spftree[1]->t_spf); + + THREAD_TIMER_OFF (area->t_lsp_l1_regenerate); + THREAD_TIMER_OFF (area->t_lsp_l2_regenerate); + XFREE (MTYPE_ISIS_AREA, area); + isis->sysid_set=0; + return CMD_SUCCESS; } diff --git a/isisd/isisd.h b/isisd/isisd.h index 2277f27c..b17982e2 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -93,6 +93,8 @@ struct isis_area struct flags flags; struct thread *t_tick; /* LSP walker */ struct thread *t_remove_aged; + struct thread *t_lsp_l1_regenerate; + struct thread *t_lsp_l2_regenerate; int lsp_regenerate_pending[ISIS_LEVELS]; struct thread *t_lsp_refresh[ISIS_LEVELS]; -- cgit v1.2.1 From 4e60f63ccc7a46b1b8500fce657b0164d881a585 Mon Sep 17 00:00:00 2001 From: Fritz Reichmann Date: Wed, 14 Sep 2011 20:46:57 +0400 Subject: isisd: raise hello rate for DIS (BZ#539) * isis_pdu.c: Divide hello interval by three, depending if we are DIS or not. --- isisd/isis_pdu.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 34e4b03d..0896d540 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1943,6 +1943,9 @@ send_hello (struct isis_circuit *circuit, int level) memset (&hello_hdr, 0, sizeof (struct isis_lan_hello_hdr)); interval = circuit->hello_multiplier[level - 1] * circuit->hello_interval[level - 1]; + /* If we are the DIS then hello interval is divided by three, as is the hold-timer */ + if (circuit->u.bc.is_dr[level - 1]) + interval=interval/3; if (interval > USHRT_MAX) interval = USHRT_MAX; hello_hdr.circuit_t = circuit->circuit_is_type; @@ -2065,9 +2068,21 @@ send_lan_l1_hello (struct thread *thread) { struct isis_circuit *circuit; int retval; + unsigned long next_hello; circuit = THREAD_ARG (thread); assert (circuit); + + if (!circuit->area) { + return ISIS_OK; + } + + /* Pseudonode sends hellos three times more than the other nodes */ + if (circuit->u.bc.is_dr[0]) + next_hello=circuit->hello_interval[0]/3+1; + else + next_hello=circuit->hello_interval[0]; + circuit->u.bc.t_send_lan_hello[0] = NULL; if (circuit->u.bc.run_dr_elect[0]) @@ -2078,7 +2093,7 @@ send_lan_l1_hello (struct thread *thread) /* set next timer thread */ THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0], send_lan_l1_hello, circuit, - isis_jitter (circuit->hello_interval[0], IIH_JITTER)); + isis_jitter (next_hello, IIH_JITTER)); return retval; } @@ -2088,6 +2103,7 @@ send_lan_l2_hello (struct thread *thread) { struct isis_circuit *circuit; int retval; + unsigned long next_hello; circuit = THREAD_ARG (thread); assert (circuit); @@ -2096,6 +2112,12 @@ send_lan_l2_hello (struct thread *thread) return ISIS_OK; } + /* Pseudonode sends hellos three times more than the other nodes */ + if (circuit->u.bc.is_dr[1]) + next_hello=circuit->hello_interval[1]/3+1; + else + next_hello=circuit->hello_interval[1]; + circuit->u.bc.t_send_lan_hello[1] = NULL; if (circuit->u.bc.run_dr_elect[1]) @@ -2106,7 +2128,7 @@ send_lan_l2_hello (struct thread *thread) /* set next timer thread */ THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1], send_lan_l2_hello, circuit, - isis_jitter (circuit->hello_interval[1], IIH_JITTER)); + isis_jitter (next_hello, IIH_JITTER)); return retval; } -- cgit v1.2.1 From e7da9d51dff9d244711758d3019381447a6d5657 Mon Sep 17 00:00:00 2001 From: Roman Hoog Antink Date: Thu, 15 Sep 2011 11:47:00 +0400 Subject: doc: fix typo --- HACKING.pending | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.pending b/HACKING.pending index 25ea0bd4..5e0defd8 100644 --- a/HACKING.pending +++ b/HACKING.pending @@ -28,7 +28,7 @@ the list have been stored. 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 poing of 0.99.17 +takes place on the branch mtr, which has a branch point of 0.99.17 * posted patches -- cgit v1.2.1 From 254f118d8671926f946a0b7221f89794cf4bf732 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 15 Sep 2011 15:40:47 +0400 Subject: ospfd: remove unused macro --- ospfd/ospfd.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b24b3ced..6eeaaf99 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -72,10 +72,6 @@ #define OSPF_ALLSPFROUTERS 0xe0000005 /* 224.0.0.5 */ #define OSPF_ALLDROUTERS 0xe0000006 /* 224.0.0.6 */ -/* XXX Where is this used? And why it was used only if compiled with - * NSSA support. */ -#define OSPF_LOOPer 0x7f000000 /* 127.0.0.0 */ - #define OSPF_AREA_BACKBONE 0x00000000 /* 0.0.0.0 */ /* OSPF Authentication Type. */ -- cgit v1.2.1 From dda8187956966b2cc977855603a5beeeada3cc76 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Thu, 15 Sep 2011 20:00:33 +0400 Subject: configure: test for glibc backtrace even without glibc. Other platform may have compatible facilities. --- configure.ac | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 75f99a64..4ea873b2 100755 --- a/configure.ac +++ b/configure.ac @@ -1440,14 +1440,12 @@ AC_SUBST(LIBCAP) dnl --------------------------- dnl check for glibc 'backtrace' dnl --------------------------- -if test "${glibc}" = "yes"; then - AC_CHECK_HEADER([execinfo.h], - [AC_CHECK_FUNC([backtrace], - [AC_DEFINE(HAVE_GLIBC_BACKTRACE,,[Glibc backtrace]) - AC_DEFINE(HAVE_STACK_TRACE,,[Stack symbol decoding]) - ]) - ]) -fi +AC_CHECK_HEADER([execinfo.h], + [AC_CHECK_FUNC([backtrace], + [AC_DEFINE(HAVE_GLIBC_BACKTRACE,,[Glibc backtrace]) + AC_DEFINE(HAVE_STACK_TRACE,,[Stack symbol decoding]) + ]) +]) dnl ----------------------------------------- dnl check for malloc mallinfo struct and call -- cgit v1.2.1 From d0511bd9b09a6952f18bf3a926de759638a5cda7 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 19 Sep 2011 16:30:47 +0400 Subject: bgpd: check LOCAL_PREF attribute flags (BZ#674) * bgp_attr.c * bgp_attr_local_pref(): accept extra argument, add checks for "optional" and "transitive" bits, log each error condition independently * bgp_attr_parse(): provide extra argument --- bgpd/bgp_attr.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index f34a7565..fe2d20e8 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -965,8 +965,33 @@ bgp_attr_med (struct peer *peer, bgp_size_t length, /* Local preference attribute. */ static int bgp_attr_local_pref (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag) + struct attr *attr, u_char flag, u_char *startp) { + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + { + zlog (peer->log, LOG_ERR, + "LOCAL_PREF attribute must be flagged as \"well-known\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + { + zlog (peer->log, LOG_ERR, + "LOCAL_PREF attribute must be flagged as \"transitive\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + /* If it is contained in an UPDATE message that is received from an external peer, then this attribute MUST be ignored by the receiving speaker. */ @@ -1644,7 +1669,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_med (peer, length, attr, flag, startp); break; case BGP_ATTR_LOCAL_PREF: - ret = bgp_attr_local_pref (peer, length, attr, flag); + ret = bgp_attr_local_pref (peer, length, attr, flag, startp); break; case BGP_ATTR_ATOMIC_AGGREGATE: ret = bgp_attr_atomic (peer, length, attr, flag); -- cgit v1.2.1 From 7d25f1883f9a391ad16ec57c06ae71df616b00d8 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 20 Sep 2011 10:54:25 +0400 Subject: bgpd: check MULTI_EXIT_DISC attr flags (BZ#677) * bgp_attr.c * bgp_attr_med(): add checks for "optional", "transitive" and "partial" bits, log each error condition independently --- bgpd/bgp_attr.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index fe2d20e8..9b2c0162 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -942,6 +942,38 @@ bgp_attr_med (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + { + zlog (peer->log, LOG_ERR, + "MULTI_EXIT_DISC attribute must be flagged as \"optional\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + { + zlog (peer->log, LOG_ERR, + "MULTI_EXIT_DISC attribute must not be flagged as \"transitive\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + { + zlog (peer->log, LOG_ERR, + "MULTI_EXIT_DISC attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + /* Length check. */ if (length != 4) { -- cgit v1.2.1 From ca22cc4cc397dac8f3bf57eca516360085d44214 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 20 Sep 2011 14:43:50 +0400 Subject: bgpd: check ATOMIC_AGGREGATE attr flags (BZ#678) * bgp_attr.c * bgp_attr_atomic(): accept extra argument, add checks for "optional", "transitive" and "partial" bits, log each error condition independently * bgp_attr_parse(): provide extra argument --- bgpd/bgp_attr.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 9b2c0162..989c22b1 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1047,8 +1047,44 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, /* Atomic aggregate. */ static int bgp_attr_atomic (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag) + struct attr *attr, u_char flag, u_char *startp) { + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + { + zlog (peer->log, LOG_ERR, + "ATOMIC_AGGREGATE attribute must not be flagged as \"optional\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + { + zlog (peer->log, LOG_ERR, + "ATOMIC_AGGREGATE attribute must be flagged as \"transitive\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + { + zlog (peer->log, LOG_ERR, + "ATOMIC_AGGREGATE attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + + /* Length check. */ if (length != 0) { zlog (peer->log, LOG_ERR, "Bad atomic aggregate length %d", length); @@ -1704,7 +1740,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_local_pref (peer, length, attr, flag, startp); break; case BGP_ATTR_ATOMIC_AGGREGATE: - ret = bgp_attr_atomic (peer, length, attr, flag); + ret = bgp_attr_atomic (peer, length, attr, flag, startp); break; case BGP_ATTR_AGGREGATOR: ret = bgp_attr_aggregator (peer, length, attr, flag); -- cgit v1.2.1 From 614da2bf57d7df965d41869d1aa8321210d6560e Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Wed, 21 Sep 2011 17:41:41 +0400 Subject: lib: provide more information in case of failed LOOKUP. * log.[ch] * mes_lookup: add a parameter with the name of the message list, print the name in case of failure. * LOOKUP macro: pass the name of the message list. --- lib/log.c | 9 +++++---- lib/log.h | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/log.c b/lib/log.c index 8a7e5f3a..4afe9229 100644 --- a/lib/log.c +++ b/lib/log.c @@ -774,7 +774,8 @@ lookup (const struct message *mes, int key) * provided otherwise. */ const char * -mes_lookup (const struct message *meslist, int max, int index, const char *none) +mes_lookup (const struct message *meslist, int max, int index, + const char *none, const char *mesname) { int pos = index - meslist[0].key; @@ -797,13 +798,13 @@ mes_lookup (const struct message *meslist, int max, int index, const char *none) { const char *str = (meslist->str ? meslist->str : none); - zlog_debug ("message index %d [%s] found in position %d (max is %d)", - index, str, i, max); + zlog_debug ("message index %d [%s] found in %s at position %d (max is %d)", + index, str, mesname, i, max); return str; } } } - zlog_err("message index %d not found (max is %d)", index, max); + zlog_err("message index %d not found in %s (max is %d)", index, mesname, max); assert (none); return none; } diff --git a/lib/log.h b/lib/log.h index 1f9a6899..ee34a4ad 100644 --- a/lib/log.h +++ b/lib/log.h @@ -146,12 +146,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, "(no item found)") +#define LOOKUP(x, y) mes_lookup(x, x ## _max, y, "(no item found)", #x) extern const char *lookup (const struct message *, int); extern const char *mes_lookup (const struct message *meslist, int max, int index, - const char *no_item); + const char *no_item, const char *mesname); extern const char *zlog_priority[]; extern const char *zlog_proto_names[]; -- cgit v1.2.1 From c347846e4f917339fd7b4c122a343f93ef621c40 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Wed, 21 Sep 2011 23:13:22 +0400 Subject: bgpd: don't be confused by "unspecific" subcode in the NOTIFY message. * bgp_debug.c (bgp_notify_open_msg, bgp_notify_update_msg, bgp_notify_cease_msg, bgp_notify_capability_msg): add messages for "unspecific" subcode. --- bgpd/bgp_debug.c | 4 ++++ bgpd/bgpd.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 26b35dfc..8e161864 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -105,6 +105,7 @@ static const int bgp_notify_head_msg_max = BGP_NOTIFY_HEADER_MAX; static const struct message bgp_notify_open_msg[] = { + { BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"}, { 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"}, @@ -117,6 +118,7 @@ static const int bgp_notify_open_msg_max = BGP_NOTIFY_OPEN_MAX; static const struct message bgp_notify_update_msg[] = { + { BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"}, { 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"}, @@ -133,6 +135,7 @@ static const int bgp_notify_update_msg_max = BGP_NOTIFY_UPDATE_MAX; static const struct message bgp_notify_cease_msg[] = { + { BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"}, { BGP_NOTIFY_CEASE_MAX_PREFIX, "/Maximum Number of Prefixes Reached"}, { BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, "/Administratively Shutdown"}, { BGP_NOTIFY_CEASE_PEER_UNCONFIG, "/Peer Unconfigured"}, @@ -146,6 +149,7 @@ static const int bgp_notify_cease_msg_max = BGP_NOTIFY_CEASE_MAX; static const struct message bgp_notify_capability_msg[] = { + { BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"}, { 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/bgpd.h b/bgpd/bgpd.h index 759d2570..91773e3c 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -631,6 +631,8 @@ struct bgp_nlri #define BGP_NOTIFY_CAPABILITY_ERR 7 #define BGP_NOTIFY_MAX 8 +#define BGP_NOTIFY_SUBCODE_UNSPECIFIC 0 + /* BGP_NOTIFY_HEADER_ERR sub codes. */ #define BGP_NOTIFY_HEADER_NOT_SYNC 1 #define BGP_NOTIFY_HEADER_BAD_MESLEN 2 @@ -661,7 +663,7 @@ struct bgp_nlri #define BGP_NOTIFY_UPDATE_MAL_AS_PATH 11 #define BGP_NOTIFY_UPDATE_MAX 12 -/* BGP_NOTIFY_CEASE sub codes (draft-ietf-idr-cease-subcode-05). */ +/* BGP_NOTIFY_CEASE sub codes (RFC 4486). */ #define BGP_NOTIFY_CEASE_MAX_PREFIX 1 #define BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN 2 #define BGP_NOTIFY_CEASE_PEER_UNCONFIG 3 -- cgit v1.2.1 From 3eca6f099d5a3aac0b66dfbf98fd8be84ea426b7 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 22 Sep 2011 12:48:14 +0400 Subject: bgpd: improve NEXT_HOP attribute checks (BZ#680) * lib/prefix.h * IPV4_CLASS_DE(): new helper macro * bgp_attr.c * bgp_attr_nexthop(): add check for "partial" bit, refresh flag error reporting, explain meaning of RFC4271 section 6.3 and implement it --- bgpd/bgp_attr.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-------- lib/prefix.h | 1 + 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 989c22b1..1300ab84 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -898,17 +898,37 @@ bgp_attr_nexthop (struct peer *peer, bgp_size_t length, struct attr *attr, u_char flag, u_char *startp) { bgp_size_t total; + in_addr_t nexthop_h, nexthop_n; total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); - /* Flag check. */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL) - || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + /* Flags check. */ + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) { - zlog (peer->log, LOG_ERR, - "Origin attribute flag isn't transitive %d", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, + zlog (peer->log, LOG_ERR, + "NEXT_HOP attribute must not be flagged as \"optional\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + { + zlog (peer->log, LOG_ERR, + "NEXT_HOP attribute must be flagged as \"transitive\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + { + zlog (peer->log, LOG_ERR, + "NEXT_HOP attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; @@ -927,7 +947,26 @@ bgp_attr_nexthop (struct peer *peer, bgp_size_t length, return -1; } - attr->nexthop.s_addr = stream_get_ipv4 (peer->ibuf); + /* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP + attribute must result in a NOTIFICATION message (this is implemented below). + At the same time, semantically incorrect NEXT_HOP is more likely to be just + logged locally (this is implemented somewhere else). The UPDATE message + gets ignored in any of these cases. */ + nexthop_n = stream_get_ipv4 (peer->ibuf); + nexthop_h = ntohl (nexthop_n); + if (IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h)) + { + char buf[INET_ADDRSTRLEN]; + inet_ntop (AF_INET, &nexthop_h, buf, INET_ADDRSTRLEN); + zlog (peer->log, LOG_ERR, "Martian nexthop %s", buf); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, + startp, total); + return -1; + } + + attr->nexthop.s_addr = nexthop_n; attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); return 0; diff --git a/lib/prefix.h b/lib/prefix.h index 5f1ff05c..1cb91b2a 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -112,6 +112,7 @@ struct prefix_rd #define IPV4_NET0(a) ((((u_int32_t) (a)) & 0xff000000) == 0x00000000) #define IPV4_NET127(a) ((((u_int32_t) (a)) & 0xff000000) == 0x7f000000) #define IPV4_LINKLOCAL(a) ((((u_int32_t) (a)) & 0xffff0000) == 0xa9fe0000) +#define IPV4_CLASS_DE(a) ((u_int32_t) (a) >= 0xe0000000) /* Max bit/byte length of IPv6 address. */ #define IPV6_MAX_BYTELEN 16 -- cgit v1.2.1 From a1afbc6e1d56b06409de5e8d7d984d565817fd96 Mon Sep 17 00:00:00 2001 From: CROSS Date: Mon, 26 Sep 2011 13:17:05 +0400 Subject: bgpd: CVE-2011-3327 (ext. comm. buffer overflow) This vulnerability (CERT-FI #513254) was reported by CROSS project. They have also suggested a fix to the problem, which was found acceptable. The problem occurs when bgpd receives an UPDATE message containing 255 unknown AS_PATH attributes in Path Attribute Extended Communities. This causes a buffer overlow in bgpd. * bgp_ecommunity.c * ecommunity_ecom2str(): perform size check earlier --- bgpd/bgp_ecommunity.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 8d5fa741..e7eb0a07 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -619,6 +619,13 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format) for (i = 0; i < ecom->size; i++) { + /* Make it sure size is enough. */ + while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size) + { + str_size *= 2; + str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size); + } + /* Space between each value. */ if (! first) str_buf[str_pnt++] = ' '; @@ -662,13 +669,6 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format) break; } - /* Make it sure size is enough. */ - while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size) - { - str_size *= 2; - str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size); - } - /* Put string into buffer. */ if (encode == ECOMMUNITY_ENCODE_AS4) { -- cgit v1.2.1 From af143a26ef96ba9be7b9c0b151b7605e1c2c74cd Mon Sep 17 00:00:00 2001 From: CROSS Date: Mon, 26 Sep 2011 13:17:21 +0400 Subject: ospfd: CVE-2011-3326 (uknown LSA type segfault) This vulnerability (CERT-FI #514837) was reported by CROSS project. They have also suggested a fix to the problem, which was found acceptable. Quagga ospfd does not seem to handle unknown LSA types in a Link State Update message correctly. If LSA type is something else than one supported by Quagga, the default handling of unknown types leads to an error. * ospf_flood.c * ospf_flood(): check return value of ospf_lsa_install() --- ospfd/ospf_flood.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 41661da2..fc0bbf12 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -319,7 +319,8 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, procedure cannot overwrite the newly installed LSA until MinLSArrival seconds have elapsed. */ - new = ospf_lsa_install (ospf, nbr->oi, new); + if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) + return 0; /* unknown LSA type */ /* Acknowledge the receipt of the LSA by sending a Link State Acknowledgment packet back out the receiving interface. */ -- cgit v1.2.1 From 3d3380d4fda43924171bc0866746c85634952c99 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 13:17:52 +0400 Subject: ospfd: CVE-2011-3325 part 1 (OSPF header underrun) This vulnerability (CERT-FI #514838) was reported by CROSS project. When only 14 first bytes of a Hello packet is delivered, ospfd crashes. * ospf_packet.c * ospf_read(): add size check --- ospfd/ospf_packet.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 1066e64f..7227452a 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2367,10 +2367,19 @@ ospf_read (struct thread *thread) return 0; } - /* Adjust size to message length. */ + /* Advance from IP header to OSPF header (iph->ip_hl has been verified + by ospf_recv_packet() to be correct). */ stream_forward_getp (ibuf, iph->ip_hl * 4); - - /* Get ospf packet header. */ + + /* Make sure the OSPF header is really there. */ + if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE) + { + zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header", + stream_get_endp (ibuf) - stream_get_getp (ibuf)); + return -1; + } + + /* Now it is safe to access all fields of OSPF packet header. */ ospfh = (struct ospf_header *) STREAM_PNT (ibuf); /* associate packet with ospf interface */ -- cgit v1.2.1 From 1f54cef38dab072f1054c6cfedd9ac32af14a120 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 13:18:02 +0400 Subject: ospfd: CVE-2011-3325 part 2 (OSPF pkt type segv) This vulnerability (CERT-FI #514838) was reported by CROSS project. The error is reproducible only when ospfd debugging is enabled: * debug ospf packet all * debug ospf zebra When incoming packet header type field is set to 0x0a, ospfd will crash. * ospf_packet.c * ospf_verify_header(): add type field check * ospf_read(): perform input checks early --- ospfd/ospf_packet.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 7227452a..489b928c 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2258,6 +2258,13 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, return -1; } + /* Valid OSPFv2 packet types are 1 through 5 inclusive. */ + if (ospfh->type < 1 || ospfh->type > 5) + { + zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type); + return -1; + } + /* Check Area ID. */ if (!ospf_check_area_id (oi, ospfh)) { @@ -2385,6 +2392,17 @@ ospf_read (struct thread *thread) /* associate packet with ospf interface */ oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); + /* Verify header fields before any further processing. */ + ret = ospf_verify_header (ibuf, oi, iph, ospfh); + if (ret < 0) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("ospf_read[%s]: Header check failed, " + "dropping.", + inet_ntoa (iph->ip_src)); + return ret; + } + /* If incoming interface is passive one, ignore it. */ if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) { @@ -2494,20 +2512,6 @@ ospf_read (struct thread *thread) zlog_debug ("-----------------------------------------------------"); } - /* Some header verification. */ - ret = ospf_verify_header (ibuf, oi, iph, ospfh); - if (ret < 0) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - { - zlog_debug ("ospf_read[%s/%s]: Header check failed, " - "dropping.", - ospf_packet_type_str[ospfh->type], - inet_ntoa (iph->ip_src)); - } - return ret; - } - stream_forward_getp (ibuf, OSPF_HEADER_SIZE); /* Adjust size to message length. */ -- cgit v1.2.1 From 308687b7d73c5cacf927a3a33efbfaea627ccc09 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 13:18:36 +0400 Subject: ospf6d: CVE-2011-3324 (DD LSA assertion) This vulnerability (CERT-FI #514839) was reported by CROSS project. When Database Description LSA header list contains trailing zero octets, ospf6d tries to process this data as an LSA header. This triggers an assertion in the code and ospf6d shuts down. * ospf6_lsa.c * ospf6_lsa_is_changed(): handle header-only argument(s) appropriately, do not treat LSA length underrun as a fatal error. --- ospf6d/ospf6_lsa.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index c1db3741..a9545c33 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -163,9 +163,19 @@ ospf6_lsa_is_changed (struct ospf6_lsa *lsa1, return 1; if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length)) return 1; + /* Going beyond LSA headers to compare the payload only makes sense, when both LSAs aren't header-only. */ + if (CHECK_FLAG (lsa1->flag, OSPF6_LSA_HEADERONLY) != CHECK_FLAG (lsa2->flag, OSPF6_LSA_HEADERONLY)) + { + zlog_warn ("%s: only one of two (%s, %s) LSAs compared is header-only", __func__, lsa1->name, lsa2->name); + return 1; + } + if (CHECK_FLAG (lsa1->flag, OSPF6_LSA_HEADERONLY)) + return 0; length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header); - assert (length > 0); + /* Once upper layer verifies LSAs received, length underrun should become a warning. */ + if (length <= 0) + return 0; return memcmp (OSPF6_LSA_HEADER_END (lsa1->header), OSPF6_LSA_HEADER_END (lsa2->header), length); -- cgit v1.2.1 From 552563a1c443ec876edd92bf79f29ff3afe2c01e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 13:18:51 +0400 Subject: ospf6d: CVE-2011-3323 (fortify packet reception) This vulnerability (CERT-FI #514840) was reported by CROSS project. ospf6d processes IPv6 prefix structures in incoming packets without verifying that the declared prefix length is valid. This leads to a crash caused by out of bounds memory access. * ospf6_abr.h: new macros for size/alignment validation * ospf6_asbr.h: idem * ospf6_intra.h: idem * ospf6_lsa.h: idem * ospf6_message.h: idem * ospf6_proto.h: idem * ospf6_message.c * ospf6_packet_minlen: helper array for ospf6_packet_examin() * ospf6_lsa_minlen: helper array for ospf6_lsa_examin() * ospf6_hello_recv(): do not call ospf6_header_examin(), let upper layer verify the input data * ospf6_dbdesc_recv(): idem * ospf6_lsreq_recv(): idem * ospf6_lsupdate_recv(): idem * ospf6_lsack_recv(): idem * ospf6_prefixes_examin(): new function, implements A.4.1 * ospf6_lsa_examin(): new function, implements A.4 * ospf6_lsaseq_examin(): new function, an interface to above * ospf6_packet_examin(): new function, implements A.3 * ospf6_rxpacket_examin(): new function, replaces ospf6_header_examin() * ospf6_header_examin(): sayonara * ospf6_receive(): perform passive interface check earliest possible, employ ospf6_rxpacket_examin() --- ospf6d/ospf6_abr.h | 2 + ospf6d/ospf6_asbr.h | 1 + ospf6d/ospf6_intra.h | 6 + ospf6d/ospf6_lsa.h | 1 + ospf6d/ospf6_message.c | 547 ++++++++++++++++++++++++++++++++++++++++++------- ospf6d/ospf6_message.h | 7 + ospf6d/ospf6_proto.h | 1 + 7 files changed, 492 insertions(+), 73 deletions(-) diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h index 86d00280..816f5964 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -35,6 +35,7 @@ extern unsigned char conf_debug_ospf6_abr; (conf_debug_ospf6_abr) /* Inter-Area-Prefix-LSA */ +#define OSPF6_INTER_PREFIX_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ struct ospf6_inter_prefix_lsa { u_int32_t metric; @@ -42,6 +43,7 @@ struct ospf6_inter_prefix_lsa }; /* Inter-Area-Router-LSA */ +#define OSPF6_INTER_ROUTER_LSA_FIX_SIZE 12U struct ospf6_inter_router_lsa { u_char mbz; diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 72644dfc..db4561de 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -51,6 +51,7 @@ struct ospf6_external_info }; /* AS-External-LSA */ +#define OSPF6_AS_EXTERNAL_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ struct ospf6_as_external_lsa { u_int32_t bits_metric; diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h index 31643fd8..3810174e 100644 --- a/ospf6d/ospf6_intra.h +++ b/ospf6d/ospf6_intra.h @@ -69,6 +69,7 @@ extern u_int32_t conf_debug_ospf6_brouter_specific_area_id; conf_debug_ospf6_brouter_specific_area_id == (area_id)) /* Router-LSA */ +#define OSPF6_ROUTER_LSA_MIN_SIZE 4U struct ospf6_router_lsa { u_char bits; @@ -77,6 +78,7 @@ struct ospf6_router_lsa }; /* Link State Description in Router-LSA */ +#define OSPF6_ROUTER_LSDESC_FIX_SIZE 16U struct ospf6_router_lsdesc { u_char type; @@ -105,6 +107,7 @@ struct ospf6_router_lsdesc (((struct ospf6_router_lsdesc *)(x))->neighbor_router_id) /* Network-LSA */ +#define OSPF6_NETWORK_LSA_MIN_SIZE 4U struct ospf6_network_lsa { u_char reserved; @@ -113,6 +116,7 @@ struct ospf6_network_lsa }; /* Link State Description in Router-LSA */ +#define OSPF6_NETWORK_LSDESC_FIX_SIZE 4U struct ospf6_network_lsdesc { u_int32_t router_id; @@ -121,6 +125,7 @@ struct ospf6_network_lsdesc (((struct ospf6_network_lsdesc *)(x))->router_id) /* Link-LSA */ +#define OSPF6_LINK_LSA_MIN_SIZE 24U /* w/o 1st IPv6 prefix */ struct ospf6_link_lsa { u_char priority; @@ -131,6 +136,7 @@ struct ospf6_link_lsa }; /* Intra-Area-Prefix-LSA */ +#define OSPF6_INTRA_PREFIX_LSA_MIN_SIZE 12U /* w/o 1st IPv6 prefix */ struct ospf6_intra_prefix_lsa { u_int16_t prefix_num; diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index c5772768..13b89900 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -79,6 +79,7 @@ (ntohs (type) & OSPF6_LSTYPE_SCOPE_MASK) /* LSA Header */ +#define OSPF6_LSA_HEADER_SIZE 20U struct ospf6_lsa_header { u_int16_t age; /* LS age */ diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index beec272b..362e8a96 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -39,6 +39,11 @@ #include "ospf6_neighbor.h" #include "ospf6_interface.h" +/* for structures and macros ospf6_lsa_examin() needs */ +#include "ospf6_abr.h" +#include "ospf6_asbr.h" +#include "ospf6_intra.h" + #include "ospf6_flood.h" #include "ospf6d.h" @@ -48,6 +53,34 @@ unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0}; const char *ospf6_message_type_str[] = { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" }; +/* Minimum (besides the standard OSPF packet header) lengths for OSPF + packets of particular types, offset is the "type" field. */ +const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] = +{ + 0, + OSPF6_HELLO_MIN_SIZE, + OSPF6_DB_DESC_MIN_SIZE, + OSPF6_LS_REQ_MIN_SIZE, + OSPF6_LS_UPD_MIN_SIZE, + OSPF6_LS_ACK_MIN_SIZE +}; + +/* Minimum (besides the standard LSA header) lengths for LSAs of particular + types, offset is the "LSA function code" portion of "LSA type" field. */ +const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] = +{ + 0, + /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE, + /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE, + /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE, + /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE, + /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, + /* 0x2006 */ 0, + /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, + /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE, + /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE +}; + /* print functions */ static void @@ -226,52 +259,6 @@ ospf6_lsack_print (struct ospf6_header *oh) zlog_debug ("Trailing garbage exists"); } -/* Receive function */ -static int -ospf6_header_examin (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) -{ - u_char type; - type = OSPF6_MESSAGE_TYPE_CANONICAL (oh->type); - - /* version check */ - if (oh->version != OSPFV3_VERSION) - { - if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) - zlog_debug ("Message with unknown version"); - return MSG_NG; - } - - /* Area-ID check */ - if (oh->area_id != oi->area->area_id) - { - if (oh->area_id == BACKBONE_AREA_ID) - { - if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) - zlog_debug ("Message may be via Virtual Link: not supported"); - return MSG_NG; - } - - if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) - zlog_debug ("Area-ID mismatch"); - return MSG_NG; - } - - /* Instance-ID check */ - if (oh->instance_id != oi->instance_id) - { - if (IS_OSPF6_DEBUG_MESSAGE (type, RECV)) - zlog_debug ("Instance-ID mismatch"); - return MSG_NG; - } - - /* Router-ID check */ - if (oh->router_id == oi->area->ospf6->router_id) - zlog_warn ("Detect duplicate Router-ID"); - - return MSG_OK; -} - static void ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh) @@ -283,9 +270,6 @@ ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst, int neighborchange = 0; int backupseen = 0; - if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) - return; - hello = (struct ospf6_hello *) ((caddr_t) oh + sizeof (struct ospf6_header)); @@ -817,9 +801,6 @@ ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_neighbor *on; struct ospf6_dbdesc *dbdesc; - if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) - return; - on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { @@ -869,9 +850,6 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_lsdb *lsdb = NULL; struct ospf6_lsa *lsa; - if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) - return; - on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { @@ -946,6 +924,433 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst, thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0); } +/* Verify, that the specified memory area contains exactly N valid IPv6 + prefixes as specified by RFC5340, A.4.1. */ +static unsigned +ospf6_prefixes_examin +( + struct ospf6_prefix *current, /* start of buffer */ + unsigned length, + const u_int32_t req_num_pfxs /* always compared with the actual number of prefixes */ +) +{ + u_char requested_pfx_bytes; + u_int32_t real_num_pfxs = 0; + + while (length) + { + if (length < OSPF6_PREFIX_MIN_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized IPv6 prefix header", __func__); + return MSG_NG; + } + /* safe to look deeper */ + if (current->prefix_length > IPV6_MAX_BITLEN) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length); + return MSG_NG; + } + /* covers both fixed- and variable-sized fields */ + requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length); + if (requested_pfx_bytes > length) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized IPv6 prefix", __func__); + return MSG_NG; + } + /* next prefix */ + length -= requested_pfx_bytes; + current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes); + real_num_pfxs++; + } + if (real_num_pfxs != req_num_pfxs) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)", + __func__, req_num_pfxs, real_num_pfxs); + return MSG_NG; + } + return MSG_OK; +} + +/* Verify an LSA to have a valid length and dispatch further (where + appropriate) to check if the contents, including nested IPv6 prefixes, + is properly sized/aligned within the LSA. Note that this function gets + LSA type in network byte order, uses in host byte order and passes to + ospf6_lstype_name() in network byte order again. */ +static unsigned +ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly) +{ + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct ospf6_as_external_lsa *as_external_lsa; + struct ospf6_link_lsa *link_lsa; + unsigned exp_length; + u_int8_t ltindex; + u_int16_t lsatype; + + /* In case an additional minimum length constraint is defined for current + LSA type, make sure that this constraint is met. */ + lsatype = ntohs (lsah->type); + ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK; + if + ( + ltindex < OSPF6_LSTYPE_SIZE && + ospf6_lsa_minlen[ltindex] && + lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE + ) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen); + return MSG_NG; + } + switch (lsatype) + { + case OSPF6_LSTYPE_ROUTER: + /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed + by N>=0 interface descriptions. */ + if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: interface description alignment error", __func__); + return MSG_NG; + } + break; + case OSPF6_LSTYPE_NETWORK: + /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes + followed by N>=0 attached router descriptions. */ + if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: router description alignment error", __func__); + return MSG_NG; + } + break; + case OSPF6_LSTYPE_INTER_PREFIX: + /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes + followed by 3-4 fields of a single IPv6 prefix. */ + if (headeronly) + break; + return ospf6_prefixes_examin + ( + (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE), + lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE, + 1 + ); + case OSPF6_LSTYPE_INTER_ROUTER: + /* RFC5340 A.4.6, fixed-size LSA. */ + if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen); + return MSG_NG; + } + break; + case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */ + case OSPF6_LSTYPE_TYPE_7: + /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes + followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields: + 16 bytes of forwarding address, 4 bytes of external route tag, + 4 bytes of referenced link state ID. */ + if (headeronly) + break; + as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); + exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE; + /* To find out if the last optional field (Referenced Link State ID) is + assumed in this LSA, we need to access fixed fields of the IPv6 + prefix before ospf6_prefix_examin() confirms its sizing. */ + if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen); + return MSG_NG; + } + /* forwarding address */ + if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) + exp_length += 16; + /* external route tag */ + if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) + exp_length += 4; + /* referenced link state ID */ + if (as_external_lsa->prefix.u._prefix_referenced_lstype) + exp_length += 4; + /* All the fixed-size fields (mandatory and optional) must fit. I.e., + this check does not include any IPv6 prefix fields. */ + if (exp_length > lsalen) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen); + return MSG_NG; + } + /* The last call completely covers the remainder (IPv6 prefix). */ + return ospf6_prefixes_examin + ( + (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE), + lsalen - exp_length, + 1 + ); + case OSPF6_LSTYPE_LINK: + /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed + by N>=0 IPv6 prefix blocks (with N declared beforehand). */ + if (headeronly) + break; + link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); + return ospf6_prefixes_examin + ( + (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE), + lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE, + ntohl (link_lsa->prefix_num) /* 32 bits */ + ); + case OSPF6_LSTYPE_INTRA_PREFIX: + /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes + followed by N>=0 IPv6 prefixes (with N declared beforehand). */ + if (headeronly) + break; + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); + return ospf6_prefixes_examin + ( + (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE), + lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE, + ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */ + ); + } + /* No additional validation is possible for unknown LSA types, which are + themselves valid in OPSFv3, hence the default decision is to accept. */ + return MSG_OK; +} + +/* Verify if the provided input buffer is a valid sequence of LSAs. This + includes verification of LSA blocks length/alignment and dispatching + of deeper-level checks. */ +static unsigned +ospf6_lsaseq_examin +( + struct ospf6_lsa_header *lsah, /* start of buffered data */ + size_t length, + const u_char headeronly, + /* When declared_num_lsas is not 0, compare it to the real number of LSAs + and treat the difference as an error. */ + const u_int32_t declared_num_lsas +) +{ + u_int32_t counted_lsas = 0; + + while (length) + { + u_int16_t lsalen; + if (length < OSPF6_LSA_HEADER_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized (%u B) trailing (#%u) LSA header", + __func__, length, counted_lsas); + return MSG_NG; + } + /* save on ntohs() calls here and in the LSA validator */ + lsalen = OSPF6_LSA_SIZE (lsah); + if (lsalen < OSPF6_LSA_HEADER_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: malformed LSA header #%u, declared length is %u B", + __func__, counted_lsas, lsalen); + return MSG_NG; + } + if (headeronly) + { + /* less checks here and in ospf6_lsa_examin() */ + if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1)) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__, + ospf6_lstype_name (lsah->type), counted_lsas); + return MSG_NG; + } + lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); + length -= OSPF6_LSA_HEADER_SIZE; + } + else + { + /* make sure the input buffer is deep enough before further checks */ + if (lsalen > length) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %u B", + __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length); + return MSG_NG; + } + if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0)) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: anomaly in %s LSA #%u", __func__, + ospf6_lstype_name (lsah->type), counted_lsas); + return MSG_NG; + } + lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen); + length -= lsalen; + } + counted_lsas++; + } + + if (declared_num_lsas && counted_lsas != declared_num_lsas) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)", + __func__, declared_num_lsas, counted_lsas); + return MSG_NG; + } + return MSG_OK; +} + +/* Verify a complete OSPF packet for proper sizing/alignment. */ +static unsigned +ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) +{ + struct ospf6_lsupdate *lsupd; + unsigned test; + + /* length, 1st approximation */ + if (bytesonwire < OSPF6_HEADER_SIZE) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire); + return MSG_NG; + } + /* Now it is safe to access header fields. */ + if (bytesonwire != ntohs (oh->length)) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: packet length error (%u real, %u declared)", + __func__, bytesonwire, ntohs (oh->length)); + return MSG_NG; + } + /* version check */ + if (oh->version != OSPFV3_VERSION) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version); + return MSG_NG; + } + /* length, 2nd approximation */ + if + ( + oh->type < OSPF6_MESSAGE_TYPE_ALL && + ospf6_packet_minlen[oh->type] && + bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type] + ) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: undersized (%u B) %s packet", __func__, + bytesonwire, ospf6_message_type_str[oh->type]); + return MSG_NG; + } + /* type-specific deeper validation */ + switch (oh->type) + { + case OSPF6_MESSAGE_TYPE_HELLO: + /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed + by N>=0 router-IDs. */ + if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4) + return MSG_OK; + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: alignment error in %s packet", + __func__, ospf6_message_type_str[oh->type]); + return MSG_NG; + case OSPF6_MESSAGE_TYPE_DBDESC: + /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed + by N>=0 header-only LSAs. */ + test = ospf6_lsaseq_examin + ( + (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE), + bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE, + 1, + 0 + ); + break; + case OSPF6_MESSAGE_TYPE_LSREQ: + /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */ + if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE) + return MSG_OK; + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: alignment error in %s packet", + __func__, ospf6_message_type_str[oh->type]); + return MSG_NG; + case OSPF6_MESSAGE_TYPE_LSUPDATE: + /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed + by N>=0 full LSAs (with N declared beforehand). */ + lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE); + test = ospf6_lsaseq_examin + ( + (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE), + bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE, + 0, + ntohl (lsupd->lsa_number) /* 32 bits */ + ); + break; + case OSPF6_MESSAGE_TYPE_LSACK: + /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */ + test = ospf6_lsaseq_examin + ( + (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE), + bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE, + 1, + 0 + ); + break; + default: + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: invalid (%u) message type", __func__, oh->type); + return MSG_NG; + } + if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: anomaly in %s packet", __func__, ospf6_message_type_str[oh->type]); + return test; +} + +/* Verify particular fields of otherwise correct received OSPF packet to + meet the requirements of RFC. */ +static int +ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire) +{ + char buf[2][INET_ADDRSTRLEN]; + + if (MSG_OK != ospf6_packet_examin (oh, bytesonwire)) + return MSG_NG; + + /* Area-ID check */ + if (oh->area_id != oi->area->area_id) + { + if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) + { + if (oh->area_id == BACKBONE_AREA_ID) + zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__); + else + zlog_debug + ( + "%s: Area-ID mismatch (my %s, rcvd %s)", __func__, + inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN), + inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN) + ); + } + return MSG_NG; + } + + /* Instance-ID check */ + if (oh->instance_id != oi->instance_id) + { + if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) + zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id); + return MSG_NG; + } + + /* Router-ID check */ + if (oh->router_id == oi->area->ospf6->router_id) + { + zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN)); + return MSG_NG; + } + return MSG_OK; +} + static void ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh) @@ -955,9 +1360,6 @@ ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, unsigned long num; char *p; - if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) - return; - on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { @@ -1035,8 +1437,6 @@ ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_lsdb *lsdb = NULL; assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); - if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) - return; on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) @@ -1201,11 +1601,6 @@ ospf6_receive (struct thread *thread) zlog_err ("Excess message read"); return 0; } - else if (len < sizeof (struct ospf6_header)) - { - zlog_err ("Deficient message read"); - return 0; - } oi = ospf6_interface_lookup_by_ifindex (ifindex); if (oi == NULL || oi->area == NULL) @@ -1213,8 +1608,22 @@ ospf6_receive (struct thread *thread) zlog_debug ("Message received on disabled interface"); return 0; } + if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) + { + if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug ("%s: Ignore message on passive interface %s", + __func__, oi->interface->name); + return 0; + } oh = (struct ospf6_header *) recvbuf; + if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK) + return 0; + + /* Being here means, that no sizing/alignment issues were detected in + the input packet. This renders the additional checks performed below + and also in the type-specific dispatching functions a dead code, + which can be dismissed in a cleanup-focused review round later. */ /* Log */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) @@ -1251,14 +1660,6 @@ ospf6_receive (struct thread *thread) } } - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Ignore message on passive interface %s", - oi->interface->name); - return 0; - } - switch (oh->type) { case OSPF6_MESSAGE_TYPE_HELLO: diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h index ebb6308e..b24d2e62 100644 --- a/ospf6d/ospf6_message.h +++ b/ospf6d/ospf6_message.h @@ -52,6 +52,7 @@ extern const char *ospf6_message_type_str[]; (ospf6_message_type_str[ OSPF6_MESSAGE_TYPE_CANONICAL (T) ]) /* OSPFv3 packet header */ +#define OSPF6_HEADER_SIZE 16U struct ospf6_header { u_char version; @@ -67,6 +68,7 @@ struct ospf6_header #define OSPF6_MESSAGE_END(H) ((caddr_t) (H) + ntohs ((H)->length)) /* Hello */ +#define OSPF6_HELLO_MIN_SIZE 20U struct ospf6_hello { u_int32_t interface_id; @@ -80,6 +82,7 @@ struct ospf6_hello }; /* Database Description */ +#define OSPF6_DB_DESC_MIN_SIZE 12U struct ospf6_dbdesc { u_char reserved1; @@ -96,7 +99,9 @@ struct ospf6_dbdesc #define OSPF6_DBDESC_IBIT (0x04) /* initial bit */ /* Link State Request */ +#define OSPF6_LS_REQ_MIN_SIZE 0U /* It is just a sequence of entries below */ +#define OSPF6_LSREQ_LSDESC_FIX_SIZE 12U struct ospf6_lsreq_entry { u_int16_t reserved; /* Must Be Zero */ @@ -106,6 +111,7 @@ struct ospf6_lsreq_entry }; /* Link State Update */ +#define OSPF6_LS_UPD_MIN_SIZE 4U struct ospf6_lsupdate { u_int32_t lsa_number; @@ -113,6 +119,7 @@ struct ospf6_lsupdate }; /* Link State Acknowledgement */ +#define OSPF6_LS_ACK_MIN_SIZE 0U /* It is just a sequence of LSA Headers */ /* Function definition */ diff --git a/ospf6d/ospf6_proto.h b/ospf6d/ospf6_proto.h index a8c1b1a0..64625004 100644 --- a/ospf6d/ospf6_proto.h +++ b/ospf6d/ospf6_proto.h @@ -73,6 +73,7 @@ #define OSPF6_OPT_V6 (1 << 0) /* IPv6 forwarding Capability */ /* OSPF6 Prefix */ +#define OSPF6_PREFIX_MIN_SIZE 4U /* .length == 0 */ struct ospf6_prefix { u_int8_t prefix_length; -- cgit v1.2.1 From 2bb2664e2957c587d8ad2d3d1d26de981983406e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 18:37:06 +0400 Subject: version RE-0.99.17.4 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4ea873b2..42f3049e 100755 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.17.3, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.17.4, [https://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) -- cgit v1.2.1 From 992d4d1ca90025ccac2456643bc2c8cb6790350b Mon Sep 17 00:00:00 2001 From: YAMAMOTO Shigeru Date: Wed, 28 Sep 2011 21:00:14 +0400 Subject: ospfd: fix regression in recent commit commit '717750433839762d23a5f8d88fe0b4d57c8d490a' causes SEGV error, when 'oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);' returns NULL. * ospf_packet.c * ospf_read(): change a place of calling 'ospf_verify_header()' --- ospfd/ospf_packet.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 489b928c..c347f31d 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2392,16 +2392,10 @@ ospf_read (struct thread *thread) /* associate packet with ospf interface */ oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); - /* Verify header fields before any further processing. */ - ret = ospf_verify_header (ibuf, oi, iph, ospfh); - if (ret < 0) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("ospf_read[%s]: Header check failed, " - "dropping.", - inet_ntoa (iph->ip_src)); - return ret; - } + /* ospf_verify_header() relies on a valid "oi" and thus can be called only + after the passive/backbone/other checks below are passed. These checks + in turn access the fields of unverified "ospfh" structure for their own + purposes and must remain very accurate in doing this. */ /* If incoming interface is passive one, ignore it. */ if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) @@ -2493,6 +2487,17 @@ ospf_read (struct thread *thread) return 0; } + /* Verify more OSPF header fields. */ + ret = ospf_verify_header (ibuf, oi, iph, ospfh); + if (ret < 0) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("ospf_read[%s]: Header check failed, " + "dropping.", + inet_ntoa (iph->ip_src)); + return ret; + } + /* Show debug receiving packet. */ if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) { -- cgit v1.2.1 From 792b6fa2c40f820df07caa80fbc6ed9c4191ef9b Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 29 Sep 2011 16:46:49 +0400 Subject: version RE-0.99.17.5 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 42f3049e..16e6d950 100755 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.17.4, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.17.5, [https://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) -- cgit v1.2.1 From d1e2faa40e17fe8f3db591021994d2f5e8b11335 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 28 Sep 2011 14:23:35 +0400 Subject: IPv6 transport class suppport IPv6 supports the same concept of differentiated service for routing protocols as IPv4, but like too many things, the standards committee decided that having two names for the same thing wasn't good enough and introduced a third more generic term transport class. The socket option to set transport class works the same as IPv4, but the arguments are different. * lib/sockopt.[ch] * setsockopt_ipv6_tclass(): new function * bgpd/bgp_network.c * bgp_connect(): set socket option * bgp_listener(): set socket option * ospf6d/ospf6_network.c * ospf6_set_transport_class(): new function * ospf6_serv_sock(): set socket option * ripngd/ripngd.c * ripng_make_socket(): set socket option --- bgpd/bgp_network.c | 8 ++++++++ lib/sockopt.c | 13 ++++++++++++- lib/sockopt.h | 1 + ospf6d/ospf6_network.c | 9 +++++++++ ripngd/ripngd.c | 5 +++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 9e3427d2..b5fa948c 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -322,6 +322,10 @@ bgp_connect (struct peer *peer) #ifdef IPTOS_PREC_INTERNETCONTROL if (sockunion_family (&peer->su) == AF_INET) setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL); +# ifdef HAVE_IPV6 + else if (sockunion_family (&peer->su) == AF_INET6) + setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL); +# endif #endif if (peer->password) @@ -381,6 +385,10 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen) #ifdef IPTOS_PREC_INTERNETCONTROL if (sa->sa_family == AF_INET) setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL); +# ifdef HAVE_IPV6 + else if (sa->sa_family == AF_INET6) + setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL); +# endif #endif #ifdef IPV6_V6ONLY diff --git a/lib/sockopt.c b/lib/sockopt.c index 9ff15ca6..63858408 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -179,8 +179,19 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh) return pktinfo->ipi6_ifindex; } -#endif /* HAVE_IPV6 */ +int +setsockopt_ipv6_tclass(int sock, int tclass) +{ + int ret; + + ret = setsockopt (sock, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof (tclass)); + if (ret < 0) + zlog_warn ("Can't set IPV6_TCLASS option for fd %d to %#x: %s", + sock, tclass, safe_strerror(errno)); + return ret; +} +#endif /* HAVE_IPV6 */ /* * Process multicast socket options for IPv4 in an OS-dependent manner. diff --git a/lib/sockopt.h b/lib/sockopt.h index 69309e00..aced6d48 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -35,6 +35,7 @@ extern int setsockopt_ipv6_multicast_hops (int, int); extern int setsockopt_ipv6_unicast_hops (int, int); extern int setsockopt_ipv6_hoplimit (int, int); extern int setsockopt_ipv6_multicast_loop (int, int); +extern int setsockopt_ipv6_tclass (int, int); #endif /* HAVE_IPV6 */ /* diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 96b82af3..3372238b 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -63,6 +63,14 @@ ospf6_set_pktinfo (void) setsockopt_ipv6_pktinfo (ospf6_sock, 1); } +void +ospf6_set_transport_class (void) +{ +#ifdef IPTOS_PREC_INTERNETCONTROL + setsockopt_ipv6_tclass (ospf6_sock, IPTOS_PREC_INTERNETCONTROL); +#endif +} + void ospf6_set_checksum (void) { @@ -102,6 +110,7 @@ ospf6_serv_sock (void) #endif /*1*/ ospf6_reset_mcastloop (); ospf6_set_pktinfo (); + ospf6_set_transport_class (); ospf6_set_checksum (); /* setup global in6_addr, allspf6 and alldr6 for later use */ diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 6e32d83c..d416255c 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -117,6 +117,11 @@ ripng_make_socket (void) ret = setsockopt_ipv6_pktinfo (sock, 1); if (ret < 0) return ret; +#ifdef IPTOS_PREC_INTERNETCONTROL + ret = setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) + return ret; +#endif ret = setsockopt_ipv6_multicast_hops (sock, 255); if (ret < 0) return ret; -- cgit v1.2.1 From d14a71d7209dc642f83929e48b525631a1bb09cb Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 12 Oct 2011 15:07:34 +0400 Subject: lib: compile even without IPV6_TCLASS --- lib/sockopt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/sockopt.c b/lib/sockopt.c index 63858408..be22827f 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -183,12 +183,14 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh) int setsockopt_ipv6_tclass(int sock, int tclass) { - int ret; + int ret = 0; +#ifdef IPV6_TCLASS /* RFC3542 */ ret = setsockopt (sock, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof (tclass)); if (ret < 0) zlog_warn ("Can't set IPV6_TCLASS option for fd %d to %#x: %s", sock, tclass, safe_strerror(errno)); +#endif return ret; } #endif /* HAVE_IPV6 */ -- cgit v1.2.1 From 17801d1e8bf377ec8e4962dda0293de935629903 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Tue, 27 Sep 2011 19:27:17 +0400 Subject: vtysh: [build] silence preprocessor errors in some cases * extract.pl.in: use configured CPPFLAGS in cpp invocation. --- vtysh/extract.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 0b9ee516..6f1ee933 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -62,7 +62,7 @@ $ignore{'"show history"'} = "ignore"; foreach (@ARGV) { $file = $_; - open (FH, "cpp -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -DHAVE_IPV6 -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_srcdir@/isisd/topology @SNMP_INCLUDES@ $file |"); + open (FH, "cpp -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -DHAVE_IPV6 -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_srcdir@/isisd/topology @SNMP_INCLUDES@ @CPPFLAGS@ $file |"); local $/; undef $/; $line = ; close (FH); -- cgit v1.2.1 From 19e7654a293cd76854eb5cf98707826efb639326 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 27 Sep 2011 15:35:39 +0400 Subject: bgpd: ignore 4 bits of attribute flags byte --- bgpd/bgp_attr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 1300ab84..251f1568 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1697,7 +1697,10 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, /* Fetch attribute flag and type. */ startp = BGP_INPUT_PNT (peer); - flag = stream_getc (BGP_INPUT (peer)); + /* "The lower-order four bits of the Attribute Flags octet are + unused. They MUST be zero when sent and MUST be ignored when + received." */ + flag = 0xF0 & stream_getc (BGP_INPUT (peer)); type = stream_getc (BGP_INPUT (peer)); /* Check whether Extended-Length applies and is in bounds */ -- cgit v1.2.1 From e531d4a662749fdd2a2f83f16e0b1cd252b23ea1 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 24 Sep 2011 13:20:43 +0400 Subject: bgpd: add missing "partial" flag checks (BZ#676) ORIGIN handling function used to have "partial" bit check and recent commits added it for NEXT_HOP, MULTI_EXIT_DISC and ATOMIC_AGGREGATE cases. This commit adds "partial" check for AS_PATH and LOCAL_PREF cases, which should leave attributes 1 through 6 inclusive completely covered with attribute flags checks. * bgp_attr.c * bgp_attr_origin(): use bit-by-bit checks for better diagnostics * bgp_attr_aspath(): add flag check * bgp_attr_local_pref(): idem --- bgpd/bgp_attr.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 251f1568..7974477b 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -712,12 +712,32 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length, with the Attribute Type Code, then the Error Subcode is set to Attribute Flags Error. The Data field contains the erroneous attribute (type, length and value). */ - if (flag != BGP_ATTR_FLAG_TRANS) + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) { - zlog (peer->log, LOG_ERR, - "Origin attribute flag isn't transitive %d", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, + zlog (peer->log, LOG_ERR, + "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + { + zlog (peer->log, LOG_ERR, + "ORIGIN attribute must be flagged as \"transitive\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + { + zlog (peer->log, LOG_ERR, + "ORIGIN attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; @@ -780,15 +800,28 @@ bgp_attr_aspath (struct peer *peer, bgp_size_t length, { u_char require ; struct aspath *asp ; + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Check the attribute flags */ + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + { + zlog (peer->log, LOG_ERR, + "AS_PATH attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return NULL; + } + require = as4_path ? BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS : 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" ; @@ -801,8 +834,6 @@ bgp_attr_aspath (struct peer *peer, bgp_size_t length, "%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, @@ -1062,6 +1093,16 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, startp, total); return -1; } + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + { + zlog (peer->log, LOG_ERR, + "LOCAL_PREF attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } /* If it is contained in an UPDATE message that is received from an external peer, then this attribute MUST be ignored by the -- cgit v1.2.1 From 395ec7f5ab794eb5205a7386b890ccb9b1313580 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 27 Sep 2011 15:47:25 +0400 Subject: bgpd: improve attr flags checks Do not check each of the Optional/Transitive/Partial attribute flag bits, when their only valid combination is known in advance, but still perform bit-deep error message logging. This change assumes unused (low-order) 4 bits of the flag octet cleared. * bgp_attr.c * bgp_attr_origin(): rewrite check * bgp_attr_nexthop(): idem * bgp_attr_med(): idem * bgp_attr_local_pref(): idem * bgp_attr_atomic(): idem --- bgpd/bgp_attr.c | 205 +++++++++++++++----------------------------------------- 1 file changed, 55 insertions(+), 150 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 7974477b..9a5eb8d2 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -712,36 +712,17 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length, with the Attribute Type Code, then the Error Subcode is set to Attribute Flags Error. The Data field contains the erroneous attribute (type, length and value). */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - { - zlog (peer->log, LOG_ERR, - "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - { - zlog (peer->log, LOG_ERR, - "ORIGIN attribute must be flagged as \"transitive\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - { - zlog (peer->log, LOG_ERR, - "ORIGIN attribute must not be flagged as \"partial\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } + if (flag != BGP_ATTR_FLAG_TRANS) + { + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag); + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "ORIGIN attribute must be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "ORIGIN attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* If any recognized attribute has Attribute Length that conflicts with the expected length (based on the attribute type code), then @@ -934,36 +915,17 @@ bgp_attr_nexthop (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flags check. */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - { - zlog (peer->log, LOG_ERR, - "NEXT_HOP attribute must not be flagged as \"optional\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - { - zlog (peer->log, LOG_ERR, - "NEXT_HOP attribute must be flagged as \"transitive\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - { - zlog (peer->log, LOG_ERR, - "NEXT_HOP attribute must not be flagged as \"partial\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } + if (flag != BGP_ATTR_FLAG_TRANS) + { + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must not be flagged as \"optional\" (%u)", flag); + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* Check nexthop attribute length. */ if (length != 4) @@ -1013,36 +975,17 @@ bgp_attr_med (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - { - zlog (peer->log, LOG_ERR, - "MULTI_EXIT_DISC attribute must be flagged as \"optional\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - { - zlog (peer->log, LOG_ERR, - "MULTI_EXIT_DISC attribute must not be flagged as \"transitive\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - { - zlog (peer->log, LOG_ERR, - "MULTI_EXIT_DISC attribute must not be flagged as \"partial\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } + if (flag != BGP_ATTR_FLAG_OPTIONAL) + { + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must be flagged as \"optional\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must not be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* Length check. */ if (length != 4) @@ -1073,36 +1016,17 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - { - zlog (peer->log, LOG_ERR, - "LOCAL_PREF attribute must be flagged as \"well-known\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - { - zlog (peer->log, LOG_ERR, - "LOCAL_PREF attribute must be flagged as \"transitive\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - { - zlog (peer->log, LOG_ERR, - "LOCAL_PREF attribute must not be flagged as \"partial\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } + if (flag != BGP_ATTR_FLAG_TRANS) + { + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must not be flagged as \"optional\" (%u)", flag); + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* If it is contained in an UPDATE message that is received from an external peer, then this attribute MUST be ignored by the @@ -1133,36 +1057,17 @@ bgp_attr_atomic (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - { - zlog (peer->log, LOG_ERR, - "ATOMIC_AGGREGATE attribute must not be flagged as \"optional\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - { - zlog (peer->log, LOG_ERR, - "ATOMIC_AGGREGATE attribute must be flagged as \"transitive\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - { - zlog (peer->log, LOG_ERR, - "ATOMIC_AGGREGATE attribute must not be flagged as \"partial\" (%u)", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } + if (flag != BGP_ATTR_FLAG_TRANS) + { + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must not be flagged as \"optional\" (%u)", flag); + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* Length check. */ if (length != 0) -- cgit v1.2.1 From 566941f953b025598134109c5f9547dc4fea287e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 12 Oct 2011 13:54:21 +0400 Subject: bgpd: fix regression in improved attr flag checks Commit 2febf323411c1aed9d7694898f852ce2ef36a7e5 assumed every flag bit except optional/transitive/partial unset, which at times could not be true for "extended length" bit. * bgp_attr.c * bgp_attr_origin(): exclude BGP_ATTR_FLAG_EXTLEN from comparison * bgp_attr_nexthop(): idem * bgp_attr_med(): idem * bgp_attr_local_pref(): idem * bgp_attr_atomic(): idem --- bgpd/bgp_attr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 9a5eb8d2..07d75ab0 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -712,7 +712,7 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length, with the Attribute Type Code, then the Error Subcode is set to Attribute Flags Error. The Data field contains the erroneous attribute (type, length and value). */ - if (flag != BGP_ATTR_FLAG_TRANS) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag); @@ -915,7 +915,7 @@ bgp_attr_nexthop (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flags check. */ - if (flag != BGP_ATTR_FLAG_TRANS) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must not be flagged as \"optional\" (%u)", flag); @@ -975,7 +975,7 @@ bgp_attr_med (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_OPTIONAL) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must be flagged as \"optional\" (%u)", flag); @@ -1016,7 +1016,7 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_TRANS) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must not be flagged as \"optional\" (%u)", flag); @@ -1057,7 +1057,7 @@ bgp_attr_atomic (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_TRANS) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must not be flagged as \"optional\" (%u)", flag); -- cgit v1.2.1 From 5de1719994fd3677b361ad71ac8bd16cf9c31706 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 30 Sep 2011 15:08:54 +0400 Subject: bgpd: check ORIGINATOR_ID attribute flags * bgp_attr.c * bgp_attr_originator_id(): accept extra argument, add checks for "optional", "transitive" and "partial" bits, log each error condition independently * bgp_attr_parse(): provide extra arguments --- bgpd/bgp_attr.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 07d75ab0..e86b55be 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1287,8 +1287,24 @@ bgp_attr_community (struct peer *peer, bgp_size_t length, /* Originator ID attribute. */ static int bgp_attr_originator_id (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag) + struct attr *attr, u_char flag, u_char *startp) { + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (flag != BGP_ATTR_FLAG_OPTIONAL) + { + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must be flagged as \"optional\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must not be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } + /* Length check. */ if (length != 4) { zlog (peer->log, LOG_ERR, "Bad originator ID length %d", length); @@ -1740,7 +1756,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_community (peer, length, attr, flag); break; case BGP_ATTR_ORIGINATOR_ID: - ret = bgp_attr_originator_id (peer, length, attr, flag); + ret = bgp_attr_originator_id (peer, length, attr, flag, startp); break; case BGP_ATTR_CLUSTER_LIST: ret = bgp_attr_cluster_list (peer, length, attr, flag); -- cgit v1.2.1 From cadc4cf05da46c44a2fb596260d4ef70d7ed6011 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 30 Sep 2011 15:12:17 +0400 Subject: bgpd: check CLUSTER_LIST attribute flags * bgp_attr.c * bgp_attr_cluster_list(): accept extra argument, add checks for "optional", "transitive" and "partial" bits, log each error condition independently * bgp_attr_parse(): provide extra arguments --- bgpd/bgp_attr.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index e86b55be..778fa48c 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1326,8 +1326,23 @@ bgp_attr_originator_id (struct peer *peer, bgp_size_t length, /* Cluster list attribute. */ static int bgp_attr_cluster_list (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag) + struct attr *attr, u_char flag, u_char *startp) { + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (flag != BGP_ATTR_FLAG_OPTIONAL) + { + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must be flagged as \"optional\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must not be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* Check length. */ if (length % 4) { @@ -1759,7 +1774,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_originator_id (peer, length, attr, flag, startp); break; case BGP_ATTR_CLUSTER_LIST: - ret = bgp_attr_cluster_list (peer, length, attr, flag); + ret = bgp_attr_cluster_list (peer, length, attr, flag, startp); break; case BGP_ATTR_MP_REACH_NLRI: ret = bgp_mp_reach_parse (peer, length, attr, mp_update); -- cgit v1.2.1 From 452db84a79df073d30ecc0b3f7bdad4143020681 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 10 Oct 2011 16:52:20 +0400 Subject: bgpd: fix spelling of CLUSTER_LIST --- bgpd/bgp_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 778fa48c..c76b22b3 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -50,7 +50,7 @@ static const struct message attr_str [] = { BGP_ATTR_AGGREGATOR, "AGGREGATOR" }, { BGP_ATTR_COMMUNITIES, "COMMUNITY" }, { BGP_ATTR_ORIGINATOR_ID, "ORIGINATOR_ID" }, - { BGP_ATTR_CLUSTER_LIST, "CLUSTERLIST" }, + { BGP_ATTR_CLUSTER_LIST, "CLUSTER_LIST" }, { BGP_ATTR_DPA, "DPA" }, { BGP_ATTR_ADVERTISER, "ADVERTISER"} , { BGP_ATTR_RCID_PATH, "RCID_PATH" }, -- cgit v1.2.1 From 047d6a601f7842d445d478d51d90b006829df945 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 8 Oct 2011 13:54:48 +0400 Subject: bgpd: improve attr length error handling (BZ#679) * bgp_attr.c * bgp_attr_parse(): provide extra argument to bgp_attr_aggregator() * bgp_attr_local_pref(): use bgp_notify_send_with_data() * bgp_attr_atomic(): idem * bgp_attr_aggregator(): idem --- bgpd/bgp_attr.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index c76b22b3..8966c5ed 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1027,6 +1027,16 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } + /* Length check. */ + if (length != 4) + { + zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute length isn't 4 [%u]", length); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + startp, total); + return -1; + } /* If it is contained in an UPDATE message that is received from an external peer, then this attribute MUST be ignored by the @@ -1037,10 +1047,7 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, return 0; } - if (length == 4) - attr->local_pref = stream_getl (peer->ibuf); - else - attr->local_pref = 0; + attr->local_pref = stream_getl (peer->ibuf); /* Set atomic aggregate flag. */ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); @@ -1072,11 +1079,11 @@ bgp_attr_atomic (struct peer *peer, bgp_size_t length, /* Length check. */ if (length != 0) { - zlog (peer->log, LOG_ERR, "Bad atomic aggregate length %d", length); - - bgp_notify_send (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); + zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute length isn't 0 [%u]", length); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + startp, total); return -1; } @@ -1089,22 +1096,24 @@ bgp_attr_atomic (struct peer *peer, bgp_size_t length, /* Aggregator attribute */ static int bgp_attr_aggregator (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag) + struct attr *attr, u_char flag, u_char *startp) { int wantedlen = 6; struct attr_extra *attre = bgp_attr_extra_get (attr); + bgp_size_t total; + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */ if ( CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV ) ) wantedlen = 8; if (length != wantedlen) { - zlog (peer->log, LOG_ERR, "Aggregator length is not %d [%d]", wantedlen, length); - - bgp_notify_send (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); + zlog (peer->log, LOG_ERR, "AGGREGATOR attribute length isn't %u [%u]", wantedlen, length); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + startp, total); return -1; } @@ -1762,7 +1771,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_atomic (peer, length, attr, flag, startp); break; case BGP_ATTR_AGGREGATOR: - ret = bgp_attr_aggregator (peer, length, attr, flag); + ret = bgp_attr_aggregator (peer, length, attr, flag, startp); break; case BGP_ATTR_AS4_AGGREGATOR: ret = bgp_attr_as4_aggregator (peer, length, attr, &as4_aggregator, &as4_aggregator_addr); -- cgit v1.2.1 From efb2c331e70eb3b913aeba3b62dfb54e68bd6de0 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 10 Oct 2011 21:08:33 +0400 Subject: bgpd: add flag checks for MP_(UN)REACH_NLRI * bgp_attr.[ch] * bgp_mp_reach_parse(): add extra arguments and a uniform flag check block * bgp_mp_unreach_parse(): idem * bgp_attr_parse(): provide extra arguments * bgp_mp_attr_test.c * parse_test(): justify respective calls --- bgpd/bgp_attr.c | 42 ++++++++++++++++++++++++++++++++++++------ bgpd/bgp_attr.h | 7 ++++--- tests/bgp_mp_attr_test.c | 4 ++-- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 8966c5ed..6b5d8191 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1375,8 +1375,8 @@ bgp_attr_cluster_list (struct peer *peer, bgp_size_t length, /* Multiprotocol reachability information parse. */ int -bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, - struct bgp_nlri *mp_update) +bgp_mp_reach_parse (struct peer *peer, const bgp_size_t length, + struct attr *attr, const u_char flag, u_char *startp, struct bgp_nlri *mp_update) { afi_t afi; safi_t safi; @@ -1385,7 +1385,21 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, int ret; struct stream *s; struct attr_extra *attre = bgp_attr_extra_get(attr); - + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (flag != BGP_ATTR_FLAG_OPTIONAL) + { + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must be flagged as \"optional\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must not be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } /* Set end of packet. */ s = BGP_INPUT(peer); start = stream_get_getp(s); @@ -1509,7 +1523,8 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, /* Multiprotocol unreachable parse */ int -bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length, +bgp_mp_unreach_parse (struct peer *peer, const bgp_size_t length, + const u_char flag, u_char *startp, struct bgp_nlri *mp_withdraw) { struct stream *s; @@ -1517,6 +1532,21 @@ bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length, safi_t safi; u_int16_t withdraw_len; int ret; + bgp_size_t total; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flag checks. */ + if (flag != BGP_ATTR_FLAG_OPTIONAL) + { + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must be flagged as \"optional\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must not be flagged as \"transitive\" (%u)", flag); + if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must not be flagged as \"partial\" (%u)", flag); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); + return -1; + } s = peer->ibuf; @@ -1786,10 +1816,10 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_cluster_list (peer, length, attr, flag, startp); break; case BGP_ATTR_MP_REACH_NLRI: - ret = bgp_mp_reach_parse (peer, length, attr, mp_update); + ret = bgp_mp_reach_parse (peer, length, attr, flag, startp, mp_update); break; case BGP_ATTR_MP_UNREACH_NLRI: - ret = bgp_mp_unreach_parse (peer, length, mp_withdraw); + ret = bgp_mp_unreach_parse (peer, length, flag, startp, mp_withdraw); break; case BGP_ATTR_EXT_COMMUNITIES: ret = bgp_attr_ext_communities (peer, length, attr, flag); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index af9dcf5e..4cb70678 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -172,8 +172,9 @@ extern void cluster_unintern (struct cluster_list *); void transit_unintern (struct transit *); /* Exported for unit-test purposes only */ -extern int bgp_mp_reach_parse (struct peer *, bgp_size_t, struct attr *, - struct bgp_nlri *); -extern int bgp_mp_unreach_parse (struct peer *, bgp_size_t, struct bgp_nlri *); +extern int bgp_mp_reach_parse (struct peer *, const bgp_size_t, struct attr *, + const u_char, u_char *, struct bgp_nlri *); +extern int bgp_mp_unreach_parse (struct peer *, const bgp_size_t, const u_char, + u_char *, struct bgp_nlri *); #endif /* _QUAGGA_BGP_ATTR_H */ diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c index d6e9f0ce..9cbe9f22 100644 --- a/tests/bgp_mp_attr_test.c +++ b/tests/bgp_mp_attr_test.c @@ -449,9 +449,9 @@ parse_test (struct peer *peer, struct test_segment *t, int type) printf ("%s: %s\n", t->name, t->desc); if (type == BGP_ATTR_MP_REACH_NLRI) - ret = bgp_mp_reach_parse (peer, t->len, &attr, &nlri); + ret = bgp_mp_reach_parse (peer, t->len, &attr, BGP_ATTR_FLAG_OPTIONAL, BGP_INPUT_PNT (peer), &nlri); else - ret = bgp_mp_unreach_parse (peer, t->len, &nlri); + ret = bgp_mp_unreach_parse (peer, t->len, BGP_ATTR_FLAG_OPTIONAL, BGP_INPUT_PNT (peer), &nlri); if (!ret) { -- cgit v1.2.1 From e48591a63220a90af9276a21877d80362bc6a408 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 3 Oct 2011 14:08:01 +0400 Subject: ospfd: justify ospf_default_originate_timer() The function is implemented in ospf_lsa.c, move its "extern" declaration to ospf_lsa.h for consistency. --- ospfd/ospf_lsa.h | 1 + ospfd/ospf_zebra.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index e51f7e8e..6b2ba228 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -280,6 +280,7 @@ extern struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *); extern struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_info *); extern int ospf_external_lsa_originate_timer (struct thread *); +extern int ospf_default_originate_timer (struct thread *); extern struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t, struct in_addr, struct in_addr); extern struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *, diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 3efd8958..fbb34442 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -50,8 +50,6 @@ extern void ospf_zebra_delete (struct prefix_ipv4 *, struct ospf_route *); extern void ospf_zebra_add_discard (struct prefix_ipv4 *); extern void ospf_zebra_delete_discard (struct prefix_ipv4 *); -extern int ospf_default_originate_timer (struct thread *); - extern int ospf_redistribute_check (struct ospf *, struct external_info *, int *); extern int ospf_distribute_check_connected (struct ospf *, -- cgit v1.2.1 From 8422e8b91bc9a0f4b8381ac0474a4d5b914869a9 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 7 Oct 2011 20:43:59 +0400 Subject: doc: "[no] router zebra" does not belong to ospfd --- doc/ospfd.texi | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/ospfd.texi b/doc/ospfd.texi index 0a085db4..856a2ba0 100644 --- a/doc/ospfd.texi +++ b/doc/ospfd.texi @@ -568,10 +568,6 @@ redistributed into OSPF (@pxref{OSPF redistribute}). @deffnx {OSPF Command} {no distance ospf} {} @end deffn -@deffn {Command} {router zebra} {} -@deffnx {Command} {no router zebra} {} -@end deffn - @node Showing OSPF information @section Showing OSPF information -- cgit v1.2.1 From 1809ec13def22bc6c2c30d9e8d37a74095bcfb64 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 13 Mar 2011 01:14:08 +0300 Subject: ripngd: copy debug statements fix from ripd Doesn't ripng needs same fix as ripd. --- ripngd/ripng_debug.c | 26 +++++++++++--------------- ripngd/ripng_debug.h | 2 -- 2 files changed, 11 insertions(+), 17 deletions(-) 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) -- cgit v1.2.1 From cc0b6c122f2d01d886e1ebde15cd2e7c5442c598 Mon Sep 17 00:00:00 2001 From: John Kemp Date: Fri, 18 Mar 2011 17:52:18 +0300 Subject: bgpd: improve "monotonic" uptime correction Older versions of Quagga/Zebra would output a value in MRT table dump files for "uptime" aka "ORIGINATED" that was a WALL clock value. Given that uptime is now internally a bgp_clock MONOTONIC value, the output in the MRT files is showing up as monotonic. Note: time of MRT dump is still recorded correctly as a time() based value, so we haven't lost that value. Proposal is to correct the uptime output on the vty and in the MRT files to again display something more akin to WALL time. * bgp_dump.c: (bgp_dump_routes_func) add conditional correction * bgp_route.c: (route_vty_out_detail) make correction conditional, move variable declaration to beginning of the function --- bgpd/bgp_dump.c | 4 ++++ bgpd/bgp_route.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) 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_route.c b/bgpd/bgp_route.c index cf8e2113..b7716330 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5799,6 +5799,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; @@ -5954,8 +5957,12 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, bgp_damp_info_vty (vty, binfo); /* Line 7 display Uptime */ - time_t tbuf = time(NULL) - (bgp_clock() - 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); } -- cgit v1.2.1 From 4b6a7b902065e038f415a8b728df1709db00425d Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Wed, 30 Mar 2011 14:30:20 +0100 Subject: doc: Add dependency for quagga.pdf make target * doc/Makefile.am: pdf target needs to depend on all the input files. --- doc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 \ -- cgit v1.2.1 From f17b65213712f324314c58866c4f4f8ed9c95dc7 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 11 Apr 2011 16:33:20 +0100 Subject: zebra: trivial warning fix * zebra_routemap.c: (route_set_src) get rid of the dummy family variable. --- zebra/zebra_routemap.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) 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; -- cgit v1.2.1 From 484af2c2e0efe660e00e27647a19f1837a7fa437 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 8 Oct 2011 17:22:45 +0400 Subject: ospf6d: make some old sizing checks assertions As long as ospf6_packet_examin() is now the single checkpoint for received packets, most of the old checks performed elsewhere can be converted into assert() constructs. Malformed input data at respective points can be attributed solely to a programming error, not a malformed packet. * ospf6_message.c * ospf6_hello_print() * ospf6_dbdesc_print() * ospf6_lsreq_print() * ospf6_lsupdate_print() * ospf6_lsack_print() * ospf6_hello_recv() * ospf6_dbdesc_recv_master() * ospf6_dbdesc_recv_slave() * ospf6_lsreq_recv() * ospf6_lsupdate_recv() * ospf6_lsupdate_recv() * ospf6_lsack_recv() * ospf6_receive() --- ospf6d/ospf6_message.c | 103 +++++++------------------------------------------ 1 file changed, 13 insertions(+), 90 deletions(-) diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 362e8a96..5760874d 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -128,8 +128,7 @@ ospf6_hello_print (struct ospf6_header *oh) zlog_debug (" Neighbor: %s", neighbor); } - if (p != OSPF6_MESSAGE_END (oh)) - zlog_debug ("Trailing garbage exists"); + assert (p == OSPF6_MESSAGE_END (oh)); } void @@ -161,8 +160,7 @@ ospf6_dbdesc_print (struct ospf6_header *oh) p += sizeof (struct ospf6_lsa_header)) ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); - if (p != OSPF6_MESSAGE_END (oh)) - zlog_debug ("Trailing garbage exists"); + assert (p == OSPF6_MESSAGE_END (oh)); } void @@ -185,8 +183,7 @@ ospf6_lsreq_print (struct ospf6_header *oh) ospf6_lstype_name (e->type), id, adv_router); } - if (p != OSPF6_MESSAGE_END (oh)) - zlog_debug ("Trailing garbage exists"); + assert (p == OSPF6_MESSAGE_END (oh)); } void @@ -211,35 +208,9 @@ ospf6_lsupdate_print (struct ospf6_header *oh) p += OSPF6_LSA_SIZE (p)) { ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); - if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header)) - { - zlog_debug (" Malformed LSA length, quit printing"); - break; - } } - if (p != OSPF6_MESSAGE_END (oh)) - { - char buf[32]; - - int num = 0; - memset (buf, 0, sizeof (buf)); - - zlog_debug (" Trailing garbage exists"); - while (p < OSPF6_MESSAGE_END (oh)) - { - snprintf (buf, sizeof (buf), "%s %2x", buf, *p++); - num++; - if (num == 8) - { - zlog_debug (" %s", buf); - memset (buf, 0, sizeof (buf)); - num = 0; - } - } - if (num) - zlog_debug (" %s", buf); - } + assert (p == OSPF6_MESSAGE_END (oh)); } void @@ -255,8 +226,7 @@ ospf6_lsack_print (struct ospf6_header *oh) p += sizeof (struct ospf6_lsa_header)) ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); - if (p != OSPF6_MESSAGE_END (oh)) - zlog_debug ("Trailing garbage exists"); + assert (p == OSPF6_MESSAGE_END (oh)); } static void @@ -323,11 +293,7 @@ ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst, twoway++; } - if (p != OSPF6_MESSAGE_END (oh)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Trailing garbage ignored"); - } + assert (p == OSPF6_MESSAGE_END (oh)); /* RouterPriority check */ if (on->priority != hello->priority) @@ -560,11 +526,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh, } } - if (p != OSPF6_MESSAGE_END (oh)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Trailing garbage ignored"); - } + assert (p == OSPF6_MESSAGE_END (oh)); /* Increment sequence number */ on->dbdesc_seqnum ++; @@ -772,11 +734,7 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh, ospf6_lsa_delete (his); } - if (p != OSPF6_MESSAGE_END (oh)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Trailing garbage ignored"); - } + assert (p == OSPF6_MESSAGE_END (oh)); /* Set sequence number to Master's */ on->dbdesc_seqnum = ntohl (dbdesc->seqnum); @@ -912,11 +870,7 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst, ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list); } - if (p != OSPF6_MESSAGE_END (oh)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Trailing garbage ignored"); - } + assert (p == OSPF6_MESSAGE_END (oh)); /* schedule send lsupdate */ THREAD_OFF (on->thread_send_lsupdate); @@ -1357,7 +1311,6 @@ ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, { struct ospf6_neighbor *on; struct ospf6_lsupdate *lsupdate; - unsigned long num; char *p; on = ospf6_neighbor_lookup (oh->router_id, oi); @@ -1380,37 +1333,16 @@ ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, lsupdate = (struct ospf6_lsupdate *) ((caddr_t) oh + sizeof (struct ospf6_header)); - num = ntohl (lsupdate->lsa_number); - /* Process LSAs */ for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); p < OSPF6_MESSAGE_END (oh) && p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); p += OSPF6_LSA_SIZE (p)) { - if (num == 0) - break; - if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Malformed LSA length, quit processing"); - break; - } - ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p); - num--; } - if (num != 0) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Malformed LSA number or LSA length"); - } - if (p != OSPF6_MESSAGE_END (oh)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Trailing garbage ignored"); - } + assert (p == OSPF6_MESSAGE_END (oh)); /* RFC2328 Section 10.9: When the neighbor responds to these requests with the proper Link State Update packet(s), the Link state request @@ -1526,11 +1458,7 @@ ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst, ospf6_lsa_delete (his); } - if (p != OSPF6_MESSAGE_END (oh)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Trailing garbage ignored"); - } + assert (p == OSPF6_MESSAGE_END (oh)); } static u_char *recvbuf = NULL; @@ -1634,8 +1562,6 @@ ospf6_receive (struct thread *thread) OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name); zlog_debug (" src: %s", srcname); zlog_debug (" dst: %s", dstname); - if (len != ntohs (oh->length)) - zlog_debug ("Message length does not match actually received: %d", len); switch (oh->type) { @@ -1655,8 +1581,7 @@ ospf6_receive (struct thread *thread) ospf6_lsack_print (oh); break; default: - zlog_debug ("Unknown message"); - break; + assert (0); } } @@ -1683,9 +1608,7 @@ ospf6_receive (struct thread *thread) break; default: - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("Unknown message"); - break; + assert (0); } return 0; -- cgit v1.2.1 From cc6647f230a55f1f4fd765a2012561047d9ae6d1 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 8 Oct 2011 18:15:21 +0400 Subject: lib: make masklen2ip() safer and faster --- lib/prefix.c | 55 +++++++++++++++++++++++++++++++++++++++---------------- lib/prefix.h | 2 +- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 61a278ca..ff8abd1b 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -31,6 +31,42 @@ /* Maskbit. */ static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; +static const u_int32_t maskbytes[] = +{ + 0x00000000, /* /0 0.0.0.0 */ + 0x80000000, /* /1 128.0.0.0 */ + 0xc0000000, /* /2 192.0.0.0 */ + 0xe0000000, /* /3 224.0.0.0 */ + 0xf0000000, /* /4 240.0.0.0 */ + 0xf8000000, /* /5 248.0.0.0 */ + 0xfc000000, /* /6 252.0.0.0 */ + 0xfe000000, /* /7 254.0.0.0 */ + 0xff000000, /* /8 255.0.0.0 */ + 0xff800000, /* /9 255.128.0.0 */ + 0xffc00000, /* /10 255.192.0.0 */ + 0xffe00000, /* /11 255.224.0.0 */ + 0xfff00000, /* /12 255.240.0.0 */ + 0xfff80000, /* /13 255.248.0.0 */ + 0xfffc0000, /* /14 255.252.0.0 */ + 0xfffe0000, /* /15 255.254.0.0 */ + 0xffff0000, /* /16 255.255.0.0 */ + 0xffff8000, /* /17 255.255.128.0 */ + 0xffffc000, /* /18 255.255.192.0 */ + 0xffffe000, /* /19 255.255.224.0 */ + 0xfffff000, /* /20 255.255.240.0 */ + 0xfffff800, /* /21 255.255.248.0 */ + 0xfffffc00, /* /22 255.255.252.0 */ + 0xfffffe00, /* /23 255.255.254.0 */ + 0xffffff00, /* /24 255.255.255.0 */ + 0xffffff80, /* /25 255.255.255.128 */ + 0xffffffc0, /* /26 255.255.255.192 */ + 0xffffffe0, /* /27 255.255.255.224 */ + 0xfffffff0, /* /28 255.255.255.240 */ + 0xfffffff8, /* /29 255.255.255.248 */ + 0xfffffffc, /* /30 255.255.255.252 */ + 0xfffffffe, /* /31 255.255.255.254 */ + 0xffffffff /* /32 255.255.255.255 */ +}; /* Number of bits in prefix type. */ #ifndef PNBBY @@ -263,23 +299,10 @@ str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p) /* Convert masklen into IP address's netmask. */ void -masklen2ip (int masklen, struct in_addr *netmask) +masklen2ip (const int masklen, struct in_addr *netmask) { - u_char *pnt; - int bit; - int offset; - - memset (netmask, 0, sizeof (struct in_addr)); - pnt = (unsigned char *) netmask; - - offset = masklen / 8; - bit = masklen % 8; - - while (offset--) - *pnt++ = 0xff; - - if (bit) - *pnt = maskbit[bit]; + assert (masklen >= 0 && masklen <= 32); + netmask->s_addr = maskbytes[masklen]; } /* Convert IP address's netmask into integer. We assume netmask is diff --git a/lib/prefix.h b/lib/prefix.h index 1cb91b2a..42334649 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -176,7 +176,7 @@ extern int prefix_ipv4_any (const struct prefix_ipv4 *); extern void apply_classful_mask_ipv4 (struct prefix_ipv4 *); extern u_char ip_masklen (struct in_addr); -extern void masklen2ip (int, struct in_addr *); +extern void masklen2ip (const int, struct in_addr *); /* returns the network portion of the host address */ extern in_addr_t ipv4_network_addr (in_addr_t hostaddr, int masklen); /* given the address of a host on a network and the network mask length, -- cgit v1.2.1 From 89a7fd150d2408e4c6fe853a3461aa23a16d9111 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 11 Oct 2011 15:17:45 +0400 Subject: lib: fix endianness of masklen2ip() --- lib/prefix.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index ff8abd1b..9633a894 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -31,7 +31,7 @@ /* Maskbit. */ static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; -static const u_int32_t maskbytes[] = +static const u_int32_t maskbytes_host[] = { 0x00000000, /* /0 0.0.0.0 */ 0x80000000, /* /1 128.0.0.0 */ @@ -67,6 +67,42 @@ static const u_int32_t maskbytes[] = 0xfffffffe, /* /31 255.255.255.254 */ 0xffffffff /* /32 255.255.255.255 */ }; +static const u_int32_t maskbytes_network[] = +{ + 0x00000000, /* /0 0.0.0.0 */ + 0x00000080, /* /1 128.0.0.0 */ + 0x000000c0, /* /2 192.0.0.0 */ + 0x000000e0, /* /3 224.0.0.0 */ + 0x000000f0, /* /4 240.0.0.0 */ + 0x000000f8, /* /5 248.0.0.0 */ + 0x000000fc, /* /6 252.0.0.0 */ + 0x000000fe, /* /7 254.0.0.0 */ + 0x000000ff, /* /8 255.0.0.0 */ + 0x000080ff, /* /9 255.128.0.0 */ + 0x0000c0ff, /* /10 255.192.0.0 */ + 0x0000e0ff, /* /11 255.224.0.0 */ + 0x0000f0ff, /* /12 255.240.0.0 */ + 0x0000f8ff, /* /13 255.248.0.0 */ + 0x0000fcff, /* /14 255.252.0.0 */ + 0x0000feff, /* /15 255.254.0.0 */ + 0x0000ffff, /* /16 255.255.0.0 */ + 0x0080ffff, /* /17 255.255.128.0 */ + 0x00c0ffff, /* /18 255.255.192.0 */ + 0x00e0ffff, /* /19 255.255.224.0 */ + 0x00f0ffff, /* /20 255.255.240.0 */ + 0x00f8ffff, /* /21 255.255.248.0 */ + 0x00fcffff, /* /22 255.255.252.0 */ + 0x00feffff, /* /23 255.255.254.0 */ + 0x00ffffff, /* /24 255.255.255.0 */ + 0x80ffffff, /* /25 255.255.255.128 */ + 0xc0ffffff, /* /26 255.255.255.192 */ + 0xe0ffffff, /* /27 255.255.255.224 */ + 0xf0ffffff, /* /28 255.255.255.240 */ + 0xf8ffffff, /* /29 255.255.255.248 */ + 0xfcffffff, /* /30 255.255.255.252 */ + 0xfeffffff, /* /31 255.255.255.254 */ + 0xffffffff /* /32 255.255.255.255 */ +}; /* Number of bits in prefix type. */ #ifndef PNBBY @@ -297,12 +333,12 @@ str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p) return ret; } -/* Convert masklen into IP address's netmask. */ +/* Convert masklen into IP address's netmask (network byte order). */ void masklen2ip (const int masklen, struct in_addr *netmask) { assert (masklen >= 0 && masklen <= 32); - netmask->s_addr = maskbytes[masklen]; + netmask->s_addr = maskbytes_network[masklen]; } /* Convert IP address's netmask into integer. We assume netmask is -- cgit v1.2.1 From 7ebd47095b178e91c3c3ef514e0ddd0afe1a97a9 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 18 Oct 2011 14:20:04 +0400 Subject: bgpd: fix more regressions in attr flag checks Commit 05a4936b713b9882171d0f7fb20b8439df23939e fixed some of the attributes involved, but not all. This commit should do it. * bgp_attr.c * bgp_attr_originator_id() * bgp_attr_cluster_list() * bgp_mp_reach_parse() * bgp_mp_unreach_parse() --- bgpd/bgp_attr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 6b5d8191..dae895d7 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1302,7 +1302,7 @@ bgp_attr_originator_id (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_OPTIONAL) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must be flagged as \"optional\" (%u)", flag); @@ -1341,7 +1341,7 @@ bgp_attr_cluster_list (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_OPTIONAL) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must be flagged as \"optional\" (%u)", flag); @@ -1389,7 +1389,7 @@ bgp_mp_reach_parse (struct peer *peer, const bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_OPTIONAL) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must be flagged as \"optional\" (%u)", flag); @@ -1536,7 +1536,7 @@ bgp_mp_unreach_parse (struct peer *peer, const bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Flag checks. */ - if (flag != BGP_ATTR_FLAG_OPTIONAL) + if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must be flagged as \"optional\" (%u)", flag); -- cgit v1.2.1 From f85bab1482b0db4cfdf90a2fd50f42d6dae96b42 Mon Sep 17 00:00:00 2001 From: "Sergey Y. Afonin" Date: Thu, 27 Oct 2011 17:01:11 +0400 Subject: bgpd: revised fix to --dryrun (BZ#622) --- bgpd/bgpd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index dafbbf72..b9fdfd77 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2044,6 +2044,10 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name) } } + bgp = bgp_create (as, name); + bgp_router_id_set(bgp, &router_id_zebra); + *bgp_val = bgp; + /* Create BGP server socket, if first instance. */ if (list_isempty(bm->bgp)) { @@ -2051,10 +2055,7 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name) return BGP_ERR_INVALID_VALUE; } - bgp = bgp_create (as, name); listnode_add (bm->bgp, bgp); - bgp_router_id_set(bgp, &router_id_zebra); - *bgp_val = bgp; return 0; } -- cgit v1.2.1 From 70e3ca2ccedca2cae58bd91c968714cad0f9d5d6 Mon Sep 17 00:00:00 2001 From: Thomas Ries Date: Thu, 27 Oct 2011 17:43:38 +0400 Subject: ospfd: improve fix to CVE-2011-3326 (BZ#586) Make ospf_flood() propagate error returned by ospf_lsa_install() further to properly discard the malformed LSA, not just prevent the immediate crash. --- ospfd/ospf_flood.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index fc0bbf12..f72087b5 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -320,7 +320,7 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, MinLSArrival seconds have elapsed. */ if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) - return 0; /* unknown LSA type */ + return -1; /* unknown LSA type or any other error condition */ /* Acknowledge the receipt of the LSA by sending a Link State Acknowledgment packet back out the receiving interface. */ -- cgit v1.2.1 From 90d181bd1a7e03d41df3cb2f51530ab47d818caa Mon Sep 17 00:00:00 2001 From: Chris Luke Date: Tue, 18 Oct 2011 17:26:51 +0400 Subject: bgpd: justify capabilities for TOS setting To set the TOS bits on TCP connections, platforms that restrict capabilities need the priv level to be raised before the sockopt is set, and this requires the ZCAP_NET_ADMIN priv. * bgp_main.c: update _caps_p to include ZCAP_NET_ADMIN * bgp_network.c * bgp_connect(): request ZPRIVS_RAISE/ZPRIVS_LOWER * bgp_listener(): request ZPRIVS_RAISE earlier --- bgpd/bgp_main.c | 1 + bgpd/bgp_network.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 9d14683c..4a38c15a 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -119,6 +119,7 @@ static zebra_capabilities_t _caps_p [] = { ZCAP_BIND, ZCAP_NET_RAW, + ZCAP_NET_ADMIN, }; struct zebra_privs_t bgpd_privs = diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index b5fa948c..3355316c 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -320,12 +320,16 @@ bgp_connect (struct peer *peer) sockopt_reuseport (peer->fd); #ifdef IPTOS_PREC_INTERNETCONTROL + if (bgpd_privs.change (ZPRIVS_RAISE)) + zlog_err ("%s: could not raise privs", __func__); if (sockunion_family (&peer->su) == AF_INET) setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL); # ifdef HAVE_IPV6 else if (sockunion_family (&peer->su) == AF_INET6) setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL); # endif + if (bgpd_privs.change (ZPRIVS_LOWER)) + zlog_err ("%s: could not lower privs", __func__); #endif if (peer->password) @@ -382,6 +386,9 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen) sockopt_reuseaddr (sock); sockopt_reuseport (sock); + if (bgpd_privs.change (ZPRIVS_RAISE)) + zlog_err ("%s: could not raise privs", __func__); + #ifdef IPTOS_PREC_INTERNETCONTROL if (sa->sa_family == AF_INET) setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL); @@ -400,13 +407,10 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen) } #endif - if (bgpd_privs.change (ZPRIVS_RAISE) ) - zlog_err ("bgp_socket: could not raise privs"); - ret = bind (sock, sa, salen); en = errno; - if (bgpd_privs.change (ZPRIVS_LOWER) ) - zlog_err ("bgp_bind_address: could not lower privs"); + if (bgpd_privs.change (ZPRIVS_LOWER)) + zlog_err ("%s: could not lower privs", __func__); if (ret < 0) { -- cgit v1.2.1 From 8b1eb59bb954af49455a97dbabf65321001d0225 Mon Sep 17 00:00:00 2001 From: Dylan Hall Date: Thu, 27 Oct 2011 15:28:17 +0400 Subject: bgpd: fix "nexthop-local unchanged" (BZ#350) --- bgpd/bgpd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index b9fdfd77..0d462db9 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4844,6 +4844,11 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, && ! peer->af_group[afi][safi]) vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE); + /* Nexthop-local unchanged. */ + if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) + && ! peer->af_group[afi][safi]) + vty_out (vty, " neighbor %s nexthop-local unchanged%s", addr, VTY_NEWLINE); + /* Allow AS in. */ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) if (! peer_group_active (peer) -- cgit v1.2.1 From 188506f4c618626e3da2c1e657100315f49664ee Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 2 Feb 2010 20:16:35 +0100 Subject: lib: prefix2sockunion, prefix_common_bits helper functions prefix2sockunion converts a struct prefix* to a union sockunion *; prefix_common_bits counts the number of common bits in the prefix's address part. --- lib/prefix.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/prefix.h | 2 ++ 2 files changed, 56 insertions(+) diff --git a/lib/prefix.c b/lib/prefix.c index 9633a894..4be3ba20 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -253,6 +253,46 @@ prefix_cmp (const struct prefix *p1, const struct prefix *p2) return 0; } +/* + * Count the number of common bits in 2 prefixes. The prefix length is + * ignored for this function; the whole prefix is compared. If the prefix + * address families don't match, return -1; otherwise the return value is + * in range 0 ... maximum prefix length for the address family. + */ +int +prefix_common_bits (const struct prefix *p1, const struct prefix *p2) +{ + int pos, bit; + int length = 0; + u_char xor; + + /* Set both prefix's head pointer. */ + const u_char *pp1 = (const u_char *)&p1->u.prefix; + const u_char *pp2 = (const u_char *)&p2->u.prefix; + + if (p1->family == AF_INET) + length = IPV4_MAX_BYTELEN; +#ifdef HAVE_IPV6 + if (p1->family == AF_INET6) + length = IPV6_MAX_BYTELEN; +#endif + if (p1->family != p2->family || !length) + return -1; + + for (pos = 0; pos < length; pos++) + if (pp1[pos] != pp2[pos]) + break; + if (pos == length) + return pos * 8; + + xor = pp1[pos] ^ pp2[pos]; + for (bit = 0; bit < 8; bit++) + if (xor & (1 << (7 - bit))) + break; + + return pos * 8 + bit; +} + /* Return prefix family type string. */ const char * prefix_family_str (const struct prefix *p) @@ -629,6 +669,20 @@ sockunion2hostprefix (const union sockunion *su) return NULL; } +void +prefix2sockunion (const struct prefix *p, union sockunion *su) +{ + memset (su, 0, sizeof (*su)); + + su->sa.sa_family = p->family; + if (p->family == AF_INET) + su->sin.sin_addr = p->u.prefix4; +#ifdef HAVE_IPV6 + if (p->family == AF_INET6) + memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr)); +#endif /* HAVE_IPV6 */ +} + int prefix_blen (const struct prefix *p) { diff --git a/lib/prefix.h b/lib/prefix.h index 42334649..675f94d4 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -157,12 +157,14 @@ extern int prefix2str (const struct prefix *, char *, int); extern int prefix_match (const struct prefix *, const struct prefix *); extern int prefix_same (const struct prefix *, const struct prefix *); extern int prefix_cmp (const struct prefix *, const struct prefix *); +extern int prefix_common_bits (const struct prefix *, const struct prefix *); extern void prefix_copy (struct prefix *dest, const struct prefix *src); extern void apply_mask (struct prefix *); extern struct prefix *sockunion2prefix (const union sockunion *dest, const union sockunion *mask); extern struct prefix *sockunion2hostprefix (const union sockunion *); +extern void prefix2sockunion (const struct prefix *, union sockunion *); extern struct prefix_ipv4 *prefix_ipv4_new (void); extern void prefix_ipv4_free (struct prefix_ipv4 *); -- cgit v1.2.1 From 5d3c53b9995dd9cbfa08edfcb03a2dcb47b170f4 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 2 Feb 2010 20:18:23 +0100 Subject: bgpd: fix update-source for IPv6 (BZ#548) if update-source was given as interface name, bgpd was unconditionally trying to bind to an IPv4 address from that interface. change function to find the best-matching (number of address bits) same-family address on the interface. --- bgpd/bgp_network.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 3355316c..ecad25b0 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -258,21 +258,37 @@ bgp_bind_address (int sock, struct in_addr *addr) return 0; } -static struct in_addr * -bgp_update_address (struct interface *ifp) +static int +bgp_update_address (struct interface *ifp, const union sockunion *dst, + union sockunion *addr) { - struct prefix_ipv4 *p; + struct prefix *p, *sel, *d; struct connected *connected; struct listnode *node; + int common; + + d = sockunion2hostprefix (dst); + sel = NULL; + common = -1; for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) { - p = (struct prefix_ipv4 *) connected->address; - - if (p->family == AF_INET) - return &p->prefix; + p = connected->address; + if (p->family != d->family) + continue; + if (prefix_common_bits (p, d) > common) + { + sel = p; + common = prefix_common_bits (sel, d); + } } - return NULL; + + prefix_free (d); + if (!sel) + return 1; + + prefix2sockunion (sel, addr); + return 0; } /* Update source selection. */ @@ -280,7 +296,7 @@ static void bgp_update_source (struct peer *peer) { struct interface *ifp; - struct in_addr *addr; + union sockunion addr; /* Source is specified with interface name. */ if (peer->update_if) @@ -289,11 +305,10 @@ bgp_update_source (struct peer *peer) if (! ifp) return; - addr = bgp_update_address (ifp); - if (! addr) + if (bgp_update_address (ifp, &peer->su, &addr)) return; - bgp_bind_address (peer->fd, addr); + sockunion_bind (peer->fd, &addr, 0, &addr); } /* Source is specified with IP address. */ -- cgit v1.2.1 From d9ddd5731d31a7bc1f0a39b7e4b0944dec7a2bdc Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 2 Feb 2010 20:20:35 +0100 Subject: bgpd: remove unused function bgp_bind_address bgp_bind_address is replaced with sockunion_bind. --- bgpd/bgp_network.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index ecad25b0..bd2e2d68 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -232,32 +232,6 @@ bgp_bind (struct peer *peer) return 0; } -static int -bgp_bind_address (int sock, struct in_addr *addr) -{ - int ret; - struct sockaddr_in local; - - memset (&local, 0, sizeof (struct sockaddr_in)); - local.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - local.sin_len = sizeof(struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - memcpy (&local.sin_addr, addr, sizeof (struct in_addr)); - - if ( bgpd_privs.change (ZPRIVS_RAISE) ) - zlog_err ("bgp_bind_address: could not raise privs"); - - ret = bind (sock, (struct sockaddr *)&local, sizeof (struct sockaddr_in)); - if (ret < 0) - ; - - if (bgpd_privs.change (ZPRIVS_LOWER) ) - zlog_err ("bgp_bind_address: could not lower privs"); - - return 0; -} - static int bgp_update_address (struct interface *ifp, const union sockunion *dst, union sockunion *addr) -- cgit v1.2.1 From 337cdd69d9d5b5ef842d1be2e67126fdc6840181 Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 25 Nov 2009 20:36:06 +0000 Subject: zebra: set the interface link-layer socket address * kernel_socket.c: (ifm_read) The reorganization from commit 6fe70d1b35c189cb1e488b2c26551ba7baac6148 removed setting the interface link-layer socket address structure on routing socket platforms. This restores saving the link-layer information because it might be used elsewhere: rtm_write() when no gateway is given, if_dump_vty() and rtadv_send_packet(). --- zebra/kernel_socket.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index feeaf5d0..bd129dc2 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -319,6 +319,7 @@ int ifm_read (struct if_msghdr *ifm) { struct interface *ifp = NULL; + struct sockaddr_dl *sdl; char ifname[IFNAMSIZ]; short ifnlen = 0; caddr_t *cp; @@ -356,6 +357,7 @@ ifm_read (struct if_msghdr *ifm) RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifm_addrs, cp); RTA_ATTR_GET (NULL, RTA_NETMASK, ifm->ifm_addrs, cp); RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp); + sdl = (struct sockaddr_dl *)cp; RTA_NAME_GET (ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen); RTA_ADDR_GET (NULL, RTA_IFA, ifm->ifm_addrs, cp); RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp); @@ -454,6 +456,16 @@ ifm_read (struct if_msghdr *ifm) #endif /* __bsdi__ */ if_get_metric (ifp); + /* + * XXX sockaddr_dl contents can be larger than the structure + * definition, so the user of the stored structure must be + * careful not to read off the end. + * + * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid + */ + if (ifnlen) + memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl)); + if_add_update (ifp); } else -- cgit v1.2.1 From 3480674a41cba545a1f546e012939e286909b10c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 16 Sep 2009 02:11:00 +0200 Subject: build: fixup autoconf for cross-compiling (to OpenWRT) MALLOC/REALLOC aren't used properly (no rpl_malloc), remove them while at it, infer some sane ipforwarding method from the OS value. (v2 on that, "==" is not a proper operator for standard "test") --- configure.ac | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 16e6d950..9536443c 100755 --- a/configure.ac +++ b/configure.ac @@ -693,11 +693,9 @@ dnl ---------------------------- AC_FUNC_CHOWN AC_FUNC_FNMATCH AC_FUNC_FORK -AC_FUNC_MALLOC AC_FUNC_MEMCMP AC_FUNC_MKTIME AC_FUNC_STRFTIME -AC_FUNC_REALLOC AC_FUNC_STAT AC_FUNC_SELECT_ARGTYPES AC_FUNC_STRFTIME @@ -1009,10 +1007,18 @@ dnl ----------------------------- dnl check ipforward detect method dnl ----------------------------- AC_CACHE_CHECK([ipforward method], [quagga_cv_ipforward_method], -[for quagga_cv_ipforward_method in /proc/net/snmp /dev/ip /dev/null; -do - test x`ls $quagga_cv_ipforward_method 2>/dev/null` = x"$quagga_cv_ipforward_method" && break -done +[if test x$cross_compiling = xyes; then + if test x"$opsys" = x"gnu-linux"; then + quagga_cv_ipforward_method=/proc/net/snmp + else + quagga_cv_ipforward_method=/dev/ip + fi +else + for quagga_cv_ipforward_method in /proc/net/snmp /dev/ip /dev/null; + do + test x`ls $quagga_cv_ipforward_method 2>/dev/null` = x"$quagga_cv_ipforward_method" && break + done +fi case $quagga_cv_ipforward_method in "/proc/net/snmp") quagga_cv_ipforward_method="proc";; "/dev/ip") -- cgit v1.2.1 From 87254a3f48874d7bbb127a118781d8ad1f017178 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 27 Aug 2009 00:28:28 +0200 Subject: rib: default distance value for new protocols (v2) adding protocols and forgetting to update zebra_rib.c currently causes a beyond end of array access for the default distance value. fix by making 150 the default distance for unknown routing protocols. 150 is higher than all other IGPs but lower than iBGP (200) --- zebra/zebra_rib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 12f3fa5a..8228350f 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -67,6 +67,7 @@ static const struct {ZEBRA_ROUTE_OSPF6, 110}, {ZEBRA_ROUTE_ISIS, 115}, {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */} + /* no entry/default: 150 */ }; /* Vector for routing table. */ @@ -1511,7 +1512,10 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, /* Set default distance by route type. */ if (distance == 0) { - distance = route_info[type].distance; + if ((unsigned)type >= sizeof(route_info) / sizeof(route_info[0])) + distance = 150; + else + distance = route_info[type].distance; /* iBGP distance is 200. */ if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP)) -- cgit v1.2.1 From 6864a990771c66384a66cd6e7db443529460b0a6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 27 Aug 2009 00:27:40 +0200 Subject: zebra: fix redistribution of new protocols redistribute is currently limited to "known" protocols. there is no reason for this limitation, so, remove it. --- zebra/redistribute.c | 46 ++++++++++++---------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index a8107aeb..4276f1d0 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -245,26 +245,15 @@ zebra_redistribute_add (int command, struct zserv *client, int length) type = stream_getc (client->ibuf); - switch (type) + if (type == 0 || type >= ZEBRA_ROUTE_MAX) + return; + + if (! client->redist[type]) { - case ZEBRA_ROUTE_KERNEL: - case ZEBRA_ROUTE_CONNECT: - case ZEBRA_ROUTE_STATIC: - case ZEBRA_ROUTE_RIP: - case ZEBRA_ROUTE_RIPNG: - case ZEBRA_ROUTE_OSPF: - case ZEBRA_ROUTE_OSPF6: - case ZEBRA_ROUTE_BGP: - if (! client->redist[type]) - { - client->redist[type] = 1; - zebra_redistribute (client, type); - } - break; - default: - break; + client->redist[type] = 1; + zebra_redistribute (client, type); } -} +} void zebra_redistribute_delete (int command, struct zserv *client, int length) @@ -273,22 +262,11 @@ zebra_redistribute_delete (int command, struct zserv *client, int length) type = stream_getc (client->ibuf); - switch (type) - { - case ZEBRA_ROUTE_KERNEL: - case ZEBRA_ROUTE_CONNECT: - case ZEBRA_ROUTE_STATIC: - case ZEBRA_ROUTE_RIP: - case ZEBRA_ROUTE_RIPNG: - case ZEBRA_ROUTE_OSPF: - case ZEBRA_ROUTE_OSPF6: - case ZEBRA_ROUTE_BGP: - client->redist[type] = 0; - break; - default: - break; - } -} + if (type == 0 || type >= ZEBRA_ROUTE_MAX) + return; + + client->redist[type] = 0; +} void zebra_redistribute_default_add (int command, struct zserv *client, int length) -- cgit v1.2.1 From daca2cf463496e5844812ea13a4fafefafe4853f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 16 Sep 2009 01:52:42 +0200 Subject: lib: put route_types.txt to real use this replaces most occurences of routing protocol lists by preprocessor defines from route_types.h. the latter is autogenerated from route_types.txt by a perl script (previously awk). adding a routing protocol now is mostly a matter of changing route_types.txt and log.c. Conflicts: lib/route_types.awk --- bgpd/bgp_vty.c | 269 +++++++++++++++------------------------------------- lib/Makefile.am | 6 +- lib/log.c | 69 +++++++++----- lib/route_types.awk | 185 ------------------------------------ lib/route_types.pl | 199 ++++++++++++++++++++++++++++++++++++++ lib/route_types.txt | 10 +- lib/zebra.h | 19 ++-- ospf6d/ospf6_asbr.c | 75 ++++----------- ospfd/ospf_vty.c | 47 ++++----- zebra/zebra_vty.c | 78 +++------------ 10 files changed, 387 insertions(+), 570 deletions(-) delete mode 100644 lib/route_types.awk create mode 100755 lib/route_types.pl diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 6dd49a06..101f6765 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -8210,57 +8210,16 @@ ALIAS (show_bgp_instance_rsclient_summary, /* Redistribute VTY commands. */ -/* Utility function to convert user input route type string to route - type. */ -static int -bgp_str2route_type (int afi, const char *str) -{ - if (! str) - return 0; - - if (afi == AFI_IP) - { - if (strncmp (str, "k", 1) == 0) - return ZEBRA_ROUTE_KERNEL; - else if (strncmp (str, "c", 1) == 0) - return ZEBRA_ROUTE_CONNECT; - else if (strncmp (str, "s", 1) == 0) - return ZEBRA_ROUTE_STATIC; - else if (strncmp (str, "r", 1) == 0) - return ZEBRA_ROUTE_RIP; - else if (strncmp (str, "o", 1) == 0) - return ZEBRA_ROUTE_OSPF; - } - if (afi == AFI_IP6) - { - if (strncmp (str, "k", 1) == 0) - return ZEBRA_ROUTE_KERNEL; - else if (strncmp (str, "c", 1) == 0) - return ZEBRA_ROUTE_CONNECT; - else if (strncmp (str, "s", 1) == 0) - return ZEBRA_ROUTE_STATIC; - else if (strncmp (str, "r", 1) == 0) - return ZEBRA_ROUTE_RIPNG; - else if (strncmp (str, "o", 1) == 0) - return ZEBRA_ROUTE_OSPF6; - } - return 0; -} - DEFUN (bgp_redistribute_ipv4, bgp_redistribute_ipv4_cmd, - "redistribute (connected|kernel|ospf|rip|static)", + "redistribute " QUAGGA_IP_REDIST_STR_BGPD, "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n") + QUAGGA_IP_REDIST_HELP_STR_BGPD) { int type; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8270,20 +8229,16 @@ DEFUN (bgp_redistribute_ipv4, DEFUN (bgp_redistribute_ipv4_rmap, bgp_redistribute_ipv4_rmap_cmd, - "redistribute (connected|kernel|ospf|rip|static) route-map WORD", + "redistribute " QUAGGA_IP_REDIST_STR_BGPD " route-map WORD", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n") { int type; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8295,21 +8250,17 @@ DEFUN (bgp_redistribute_ipv4_rmap, DEFUN (bgp_redistribute_ipv4_metric, bgp_redistribute_ipv4_metric_cmd, - "redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295>", + "redistribute " QUAGGA_IP_REDIST_STR_BGPD " metric <0-4294967295>", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n") { int type; u_int32_t metric; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8322,13 +8273,9 @@ DEFUN (bgp_redistribute_ipv4_metric, DEFUN (bgp_redistribute_ipv4_rmap_metric, bgp_redistribute_ipv4_rmap_metric_cmd, - "redistribute (connected|kernel|ospf|rip|static) route-map WORD metric <0-4294967295>", + "redistribute " QUAGGA_IP_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n" "Metric for redistributed routes\n" @@ -8337,8 +8284,8 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric, int type; u_int32_t metric; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8352,13 +8299,9 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric, DEFUN (bgp_redistribute_ipv4_metric_rmap, bgp_redistribute_ipv4_metric_rmap_cmd, - "redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295> route-map WORD", + "redistribute " QUAGGA_IP_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n" "Route map reference\n" @@ -8367,8 +8310,8 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap, int type; u_int32_t metric; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8382,19 +8325,15 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap, DEFUN (no_bgp_redistribute_ipv4, no_bgp_redistribute_ipv4_cmd, - "no redistribute (connected|kernel|ospf|rip|static)", + "no redistribute " QUAGGA_IP_REDIST_STR_BGPD, NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n") + QUAGGA_IP_REDIST_HELP_STR_BGPD) { int type; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8405,21 +8344,17 @@ DEFUN (no_bgp_redistribute_ipv4, DEFUN (no_bgp_redistribute_ipv4_rmap, no_bgp_redistribute_ipv4_rmap_cmd, - "no redistribute (connected|kernel|ospf|rip|static) route-map WORD", + "no redistribute " QUAGGA_IP_REDIST_STR_BGPD " route-map WORD", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n") { int type; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8431,21 +8366,17 @@ DEFUN (no_bgp_redistribute_ipv4_rmap, DEFUN (no_bgp_redistribute_ipv4_metric, no_bgp_redistribute_ipv4_metric_cmd, - "no redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295>", + "no redistribute " QUAGGA_IP_REDIST_STR_BGPD " metric <0-4294967295>", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n") { int type; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8457,14 +8388,10 @@ DEFUN (no_bgp_redistribute_ipv4_metric, DEFUN (no_bgp_redistribute_ipv4_rmap_metric, no_bgp_redistribute_ipv4_rmap_metric_cmd, - "no redistribute (connected|kernel|ospf|rip|static) route-map WORD metric <0-4294967295>", + "no redistribute " QUAGGA_IP_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n" "Metric for redistributed routes\n" @@ -8472,8 +8399,8 @@ DEFUN (no_bgp_redistribute_ipv4_rmap_metric, { int type; - type = bgp_str2route_type (AFI_IP, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8486,14 +8413,10 @@ DEFUN (no_bgp_redistribute_ipv4_rmap_metric, ALIAS (no_bgp_redistribute_ipv4_rmap_metric, no_bgp_redistribute_ipv4_metric_rmap_cmd, - "no redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295> route-map WORD", + "no redistribute " QUAGGA_IP_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n" + QUAGGA_IP_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n" "Route map reference\n" @@ -8502,18 +8425,14 @@ ALIAS (no_bgp_redistribute_ipv4_rmap_metric, #ifdef HAVE_IPV6 DEFUN (bgp_redistribute_ipv6, bgp_redistribute_ipv6_cmd, - "redistribute (connected|kernel|ospf6|ripng|static)", + "redistribute " QUAGGA_IP6_REDIST_STR_BGPD, "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n") + QUAGGA_IP6_REDIST_HELP_STR_BGPD) { int type; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8524,20 +8443,16 @@ DEFUN (bgp_redistribute_ipv6, DEFUN (bgp_redistribute_ipv6_rmap, bgp_redistribute_ipv6_rmap_cmd, - "redistribute (connected|kernel|ospf6|ripng|static) route-map WORD", + "redistribute " QUAGGA_IP6_REDIST_STR_BGPD " route-map WORD", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n") { int type; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8549,21 +8464,17 @@ DEFUN (bgp_redistribute_ipv6_rmap, DEFUN (bgp_redistribute_ipv6_metric, bgp_redistribute_ipv6_metric_cmd, - "redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295>", + "redistribute " QUAGGA_IP6_REDIST_STR_BGPD " metric <0-4294967295>", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n") { int type; u_int32_t metric; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8576,13 +8487,9 @@ DEFUN (bgp_redistribute_ipv6_metric, DEFUN (bgp_redistribute_ipv6_rmap_metric, bgp_redistribute_ipv6_rmap_metric_cmd, - "redistribute (connected|kernel|ospf6|ripng|static) route-map WORD metric <0-4294967295>", + "redistribute " QUAGGA_IP6_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n" "Metric for redistributed routes\n" @@ -8591,8 +8498,8 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric, int type; u_int32_t metric; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8606,13 +8513,9 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric, DEFUN (bgp_redistribute_ipv6_metric_rmap, bgp_redistribute_ipv6_metric_rmap_cmd, - "redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295> route-map WORD", + "redistribute " QUAGGA_IP6_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD", "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n" "Route map reference\n" @@ -8621,8 +8524,8 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap, int type; u_int32_t metric; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8636,19 +8539,15 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap, DEFUN (no_bgp_redistribute_ipv6, no_bgp_redistribute_ipv6_cmd, - "no redistribute (connected|kernel|ospf6|ripng|static)", + "no redistribute " QUAGGA_IP6_REDIST_STR_BGPD, NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n") + QUAGGA_IP6_REDIST_HELP_STR_BGPD) { int type; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8659,21 +8558,17 @@ DEFUN (no_bgp_redistribute_ipv6, DEFUN (no_bgp_redistribute_ipv6_rmap, no_bgp_redistribute_ipv6_rmap_cmd, - "no redistribute (connected|kernel|ospf6|ripng|static) route-map WORD", + "no redistribute " QUAGGA_IP6_REDIST_STR_BGPD " route-map WORD", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n") { int type; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8685,21 +8580,17 @@ DEFUN (no_bgp_redistribute_ipv6_rmap, DEFUN (no_bgp_redistribute_ipv6_metric, no_bgp_redistribute_ipv6_metric_cmd, - "no redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295>", + "no redistribute " QUAGGA_IP6_REDIST_STR_BGPD " metric <0-4294967295>", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n") { int type; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8711,14 +8602,10 @@ DEFUN (no_bgp_redistribute_ipv6_metric, DEFUN (no_bgp_redistribute_ipv6_rmap_metric, no_bgp_redistribute_ipv6_rmap_metric_cmd, - "no redistribute (connected|kernel|ospf6|ripng|static) route-map WORD metric <0-4294967295>", + "no redistribute " QUAGGA_IP6_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Route map reference\n" "Pointer to route-map entries\n" "Metric for redistributed routes\n" @@ -8726,8 +8613,8 @@ DEFUN (no_bgp_redistribute_ipv6_rmap_metric, { int type; - type = bgp_str2route_type (AFI_IP6, argv[0]); - if (! type) + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_BGP) { vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -8740,14 +8627,10 @@ DEFUN (no_bgp_redistribute_ipv6_rmap_metric, ALIAS (no_bgp_redistribute_ipv6_rmap_metric, no_bgp_redistribute_ipv6_metric_rmap_cmd, - "no redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295> route-map WORD", + "no redistribute " QUAGGA_IP6_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD", NO_STR "Redistribute information from another routing protocol\n" - "Connected\n" - "Kernel routes\n" - "Open Shurtest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n" + QUAGGA_IP6_REDIST_HELP_STR_BGPD "Metric for redistributed routes\n" "Default metric\n" "Route map reference\n" diff --git a/lib/Makefile.am b/lib/Makefile.am index 315e919b..890cc5ca 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -29,10 +29,10 @@ pkginclude_HEADERS = \ privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ workqueue.h route_types.h -EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.awk route_types.txt +EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.pl route_types.txt memtypes.h: $(srcdir)/memtypes.c $(srcdir)/memtypes.awk ($(GAWK) -f $(srcdir)/memtypes.awk $(srcdir)/memtypes.c > $@) -route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.awk - ($(GAWK) -f $(srcdir)/route_types.awk $(srcdir)/route_types.txt > $@) +route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.pl + @PERL@ $(srcdir)/route_types.pl < $(srcdir)/route_types.txt > $@ diff --git a/lib/log.c b/lib/log.c index 4afe9229..7edc5c4c 100644 --- a/lib/log.c +++ b/lib/log.c @@ -20,6 +20,8 @@ * 02111-1307, USA. */ +#define QUAGGA_DEFINE_DESC_TABLE + #include #include "log.h" @@ -817,29 +819,6 @@ safe_strerror(int errnum) return (s != NULL) ? s : "Unknown error"; } -struct zebra_desc_table -{ - unsigned int type; - const char *string; - char chr; -}; - -#define DESC_ENTRY(T,S,C) [(T)] = { (T), (S), (C) } -static const struct zebra_desc_table route_types[] = { - DESC_ENTRY (ZEBRA_ROUTE_SYSTEM, "system", 'X' ), - DESC_ENTRY (ZEBRA_ROUTE_KERNEL, "kernel", 'K' ), - DESC_ENTRY (ZEBRA_ROUTE_CONNECT, "connected", 'C' ), - DESC_ENTRY (ZEBRA_ROUTE_STATIC, "static", 'S' ), - DESC_ENTRY (ZEBRA_ROUTE_RIP, "rip", 'R' ), - DESC_ENTRY (ZEBRA_ROUTE_RIPNG, "ripng", 'R' ), - DESC_ENTRY (ZEBRA_ROUTE_OSPF, "ospf", 'O' ), - DESC_ENTRY (ZEBRA_ROUTE_OSPF6, "ospf6", 'O' ), - DESC_ENTRY (ZEBRA_ROUTE_ISIS, "isis", 'I' ), - DESC_ENTRY (ZEBRA_ROUTE_BGP, "bgp", 'B' ), - DESC_ENTRY (ZEBRA_ROUTE_HSLS, "hsls", 'H' ), -}; -#undef DESC_ENTRY - #define DESC_ENTRY(T) [(T)] = { (T), (#T), '\0' } static const struct zebra_desc_table command_types[] = { DESC_ENTRY (ZEBRA_INTERFACE_ADD), @@ -929,4 +908,48 @@ proto_name2num(const char *s) return route_types[i].type; return -1; } + #undef RTSIZE + +int +proto_redistnum(int afi, const char *s) +{ + if (! s) + return -1; + + if (afi == AFI_IP) + { + if (strncmp (s, "k", 1) == 0) + return ZEBRA_ROUTE_KERNEL; + else if (strncmp (s, "c", 1) == 0) + return ZEBRA_ROUTE_CONNECT; + else if (strncmp (s, "s", 1) == 0) + return ZEBRA_ROUTE_STATIC; + else if (strncmp (s, "r", 1) == 0) + return ZEBRA_ROUTE_RIP; + else if (strncmp (s, "o", 1) == 0) + return ZEBRA_ROUTE_OSPF; + else if (strncmp (s, "i", 1) == 0) + return ZEBRA_ROUTE_ISIS; + else if (strncmp (s, "b", 1) == 0) + return ZEBRA_ROUTE_BGP; + } + if (afi == AFI_IP6) + { + if (strncmp (s, "k", 1) == 0) + return ZEBRA_ROUTE_KERNEL; + else if (strncmp (s, "c", 1) == 0) + return ZEBRA_ROUTE_CONNECT; + else if (strncmp (s, "s", 1) == 0) + return ZEBRA_ROUTE_STATIC; + else if (strncmp (s, "r", 1) == 0) + return ZEBRA_ROUTE_RIPNG; + else if (strncmp (s, "o", 1) == 0) + return ZEBRA_ROUTE_OSPF6; + else if (strncmp (s, "i", 1) == 0) + return ZEBRA_ROUTE_ISIS; + else if (strncmp (s, "b", 1) == 0) + return ZEBRA_ROUTE_BGP; + } + return -1; +} diff --git a/lib/route_types.awk b/lib/route_types.awk deleted file mode 100644 index 6cfd5377..00000000 --- a/lib/route_types.awk +++ /dev/null @@ -1,185 +0,0 @@ -# Scan a file of route-type definitions (see eg route_types.txt) and -# generate a corresponding header file with: -# -# - enum of Zserv route-types -# - redistribute strings for the various Quagga daemons -# -# See route_types.txt for the format. -# -# - -BEGIN { - FS="[,]"; - - # globals - exitret = 0; - tcount = 0; - - # formats for output - ## the define format - redist_def_fmt = "#define QUAGGA_REDIST_STR_%s \\\n"; - ## DEFUN/vty route-type argument - redist_str_fmt = "\"(%s)\"\n"; - redist_help_def_fmt = "#define QUAGGA_REDIST_HELP_STR_%s"; - redist_help_str_fmt = " \\\n \"%s\\n\""; - - # header - header = "/* Auto-generated from route_types.txt by " ARGV[0] ". */\n"; - header = header "/* Do not edit! */\n"; - header = header "\n#ifndef _QUAGGA_ROUTE_TYPES_H\n"; - header = header "#define _QUAGGA_ROUTE_TYPES_H\n"; - footer = "#endif /* _QUAGGA_ROUTE_TYPES_H */\n"; - printf ("%s\n", header); -} - -# Chomp comment lines -($0 ~ /^#/) { - next; -} - -# get rid of the commas, leading/trailling whitespace and -# quotes -{ - for (i = 1; i <= NF; i++) { - #print "before:" $i; - $i = gensub(/^[[:blank:]]*(.*)[,]*.*/, "\\1", "g",$i); - $i = gensub(/^["](.*)["]$/, "\\1", "g", $i); - #print "after :" $i; - } -} - -# 7 field format: -# type cname daemon C 4 6 short help -(NF >= 7) { - #print "7", $1, $0; - - if ($1 in types) { - print "error: attempt to redefine", $1; - exitret = 1; - exit exitret; - } - - typesbynum[tcount] = $1; - types[$1,"num"] = tcount++; - types[$1,"cname"] = $2; - types[$1,"daemon"] = $3; - types[$1,"C"] = $4; - types[$1,"4"] = strtonum($5); - types[$1,"6"] = strtonum($6); - types[$1,"shelp"] = $7; - - #print "num :", types[$1,"num"] - #print "cname :", types[$1,"cname"] - #print "daemon:", types[$1,"daemon"]; - #print "char :", types[$1,"C"]; -}; - -# 2 field: type "long description" -(NF == 2) { - #print "2", $1, $2; - - if (!(($1 SUBSEP "num") in types)) { - print "error: type", $1, "must be defined before help str"; - exitret = 2; - exit exitret; - } - - types[$1,"lhelp"] = $2; -} - -END { - if (exitret) - exit exitret; - - # The enums - # not yet... - #printf("enum\n{\n"); - #for (i = 0; i < tcount; i++) { - # type = typesbynum[i]; - # if (type != "" && types[type,"num"] == i) - # printf (" %s,\n", type); - #} - #printf (" ZEBRA_ROUTE_MAX,\n};\n\n"); - - # the redistribute defines - for (i = 0; i < tcount; i++) { - type = typesbynum[i]; - - # must be a type, and must cross-check against recorded type - if (type == "" || types[type,"num"] != i) - continue; - - # ignore route types that can't be redistributed - if (!(types[type,"4"] || types[type,"6"])) - continue; - - # must have a daemon name - if (!((type SUBSEP "daemon") in types)) - continue; - if (!(daemon = types[type,"daemon"])) - continue; - - # might have done this daemon already? - if (daemon in seen_daemons) - continue; - - cname = types[type,"cname"]; - all = all "|" cname; - rstr = ""; - hstr = ""; - - # add it to the others - for (j = 0; j < tcount; j++) { - # ignore self - if (i == j) - continue; - - type2 = typesbynum[j]; - - # type2 must be valid, and self-check. - if (type2 == "" || types[type2,"num"] != j) - continue; - - # ignore different route types for the same daemon - # (eg system/kernel/connected) - if (types[type2,"daemon"] == daemon) - continue; - - if ((types[type2,"4"] && types[type,"4"]) \ - || (types[type2,"6"] && types[type,"6"])) { - - if (rstr == "") - rstr = types[type2,"cname"]; - else - rstr = rstr "|" types[type2,"cname"]; - - if ((type2 SUBSEP "lhelp") in types) - hstr2 = types[type2,"lhelp"]; - else if ((type2 SUBSEP "shelp") in types) - hstr2 = types[type2,"shelp"]; - else - hstr2 = types[type2,"cname"]; - - hstr = hstr sprintf(redist_help_str_fmt, hstr2); - } - } - - # dont double-process daemons. - seen_daemons[daemon] = 1; - - printf("/* %s */\n", daemon); - printf(redist_def_fmt, toupper(daemon)); - printf(redist_str_fmt, rstr); - printf(redist_help_def_fmt, toupper(daemon)); - printf("%s", hstr); - printf("\n\n"); - } - - #printf("#define QUAGGA_REDIST_STR_ALL %s\n",all); - -# for (i = 0; i < lcount; i++) { -# if (mlists[i] != "") -# printf (mlistformat "\n", mlists[i]); -# } - printf (footer); -} diff --git a/lib/route_types.pl b/lib/route_types.pl new file mode 100755 index 00000000..e1595afc --- /dev/null +++ b/lib/route_types.pl @@ -0,0 +1,199 @@ +#!/usr/bin/perl +## +## Scan a file of route-type definitions (see eg route_types.txt) and +## generate a corresponding header file with: +## +## - enum of Zserv route-types +## - redistribute strings for the various Quagga daemons +## +## See route_types.txt for the format. +## +## +## Copyright (C) 2009 David Lamparter. +## This file is part of GNU Zebra. +## +## GNU Zebra is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation; either version 2, or (at your option) any +## later version. +## +## GNU Zebra is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with GNU Zebra; see the file COPYING. If not, write to the Free +## Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA. +## + +use strict; + +# input processing +# +my @protos; +my %protodetail; + +my %daemons; + +while () { + # skip comments and empty lines + next if (/^\s*(#|$)/); + + # strip whitespace + chomp; + $_ =~ s/^\s*//; + $_ =~ s/\s*$//; + + # match help strings + if (/^(ZEBRA_ROUTE_[^\s]+)\s*,\s*"(.*)"$/) { + $protodetail{$1}->{'longhelp'} = $2; + next; + } + + $_ =~ s/\s*,\s*/,/g; + + # else: 7-field line + my @f = split(/,/, $_); + unless (@f == 7) { + die "invalid input on route_types line $.\n"; + } + + my $proto = $f[0]; + $f[3] = $1 if ($f[3] =~ /^'(.*)'$/); + $f[6] = $1 if ($f[6] =~ /^"(.*)"$/); + + $protodetail{$proto} = { + "number" => scalar @protos, + "type" => $f[0], + "cname" => $f[1], + "daemon" => $f[2], + "char" => $f[3], + "ipv4" => int($f[4]), + "ipv6" => int($f[5]), + "shorthelp" => $f[6], + }; + push @protos, $proto; + $daemons{$f[2]} = { + "ipv4" => int($f[4]), + "ipv6" => int($f[5]) + } unless ($f[2] eq "NULL"); +} + +# output +printf <{"ipv4"}); + push @protosv6, $p if ($protodetail{$p}->{"ipv6"}); +} +pop @protos; + +sub codelist { + my (@protos) = @_; + my (@lines) = (); + my $str = " \"Codes: "; + for my $p (@protos) { + my $s = sprintf("%s - %s, ", + $protodetail{$p}->{"char"}, + $protodetail{$p}->{"shorthelp"}); + if (length($str . $s) > 70) { + $str =~ s/ $//; + push @lines, $str . "%s\" \\\n"; + $str = " \" "; + } + $str .= $s; + } + $str =~ s/ $//; + push @lines, $str . "%s\" \\\n"; + push @lines, " \" > - selected route, * - FIB route%s%s\", \\\n"; + my @nl = (); + for (my $c = 0; $c < @lines + 1; $c++) { + push @nl, "VTY_NEWLINE" + } + return join("", @lines) ." ". join(", ", @nl); +} + +print "\n"; +printf "#define SHOW_ROUTE_V4_HEADER \\\n%s\n", codelist(@protosv4); +printf "#define SHOW_ROUTE_V6_HEADER \\\n%s\n", codelist(@protosv6); +print "\n"; + +sub collect { + my ($daemon, $ipv4, $ipv6) = @_; + my (@names, @help) = ((), ()); + for my $p (@protos) { + next if ($protodetail{$p}->{"daemon"} eq $daemon && $daemon ne "zebra"); + next unless (($ipv4 && $protodetail{$p}->{"ipv4"}) + || ($ipv6 && $protodetail{$p}->{"ipv6"})); + push @names, $protodetail{$p}->{"cname"}; + push @help, " \"".$protodetail{$p}->{"longhelp"}."\\n\""; + } + return ("\"(" . join("|", @names) . ")\"", join(" \\\n", @help)); +} + +for my $daemon (sort keys %daemons) { + next unless ($daemons{$daemon}->{"ipv4"} || $daemons{$daemon}->{"ipv6"}); + printf "/* %s */\n", $daemon; + if ($daemons{$daemon}->{"ipv4"} && $daemons{$daemon}->{"ipv6"}) { + my ($names, $help) = collect($daemon, 1, 1); + printf "#define QUAGGA_REDIST_STR_%s \\\n %s\n", uc $daemon, $names; + printf "#define QUAGGA_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help; + ($names, $help) = collect($daemon, 1, 0); + printf "#define QUAGGA_IP_REDIST_STR_%s \\\n %s\n", uc $daemon, $names; + printf "#define QUAGGA_IP_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help; + ($names, $help) = collect($daemon, 0, 1); + printf "#define QUAGGA_IP6_REDIST_STR_%s \\\n %s\n", uc $daemon, $names; + printf "#define QUAGGA_IP6_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help; + } else { + my ($names, $help) = collect($daemon, + $daemons{$daemon}->{"ipv4"}, $daemons{$daemon}->{"ipv6"}); + printf "#define QUAGGA_REDIST_STR_%s \\\n %s\n", uc $daemon, $names; + printf "#define QUAGGA_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help; + } + print "\n"; +} + +print <{"cname"}, $protodetail{$p}->{"char"}; +} + +print < "ZEBRA_INTERFACE_ADD" */ /* Map a protocol name to its number. e.g. ZEBRA_ROUTE_BGP->9*/ extern int proto_name2num(const char *s); +/* Map redistribute X argument to protocol number. + * unlike proto_name2num, this accepts shorthands and takes + * an AFI value to restrict input */ +extern int proto_redistnum(int afi, const char *s); extern const char *zserv_command_string (unsigned int command); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 685b147c..d6c1517e 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -616,27 +616,16 @@ ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix) DEFUN (ospf6_redistribute, ospf6_redistribute_cmd, - "redistribute (static|kernel|connected|ripng|bgp)", + "redistribute " QUAGGA_REDIST_STR_OSPF6D, "Redistribute\n" - "Static route\n" - "Kernel route\n" - "Connected route\n" - "RIPng route\n" - "BGP route\n" + QUAGGA_REDIST_HELP_STR_OSPF6D ) { - int type = 0; - - if (strncmp (argv[0], "sta", 3) == 0) - type = ZEBRA_ROUTE_STATIC; - else if (strncmp (argv[0], "ker", 3) == 0) - type = ZEBRA_ROUTE_KERNEL; - else if (strncmp (argv[0], "con", 3) == 0) - type = ZEBRA_ROUTE_CONNECT; - else if (strncmp (argv[0], "rip", 3) == 0) - type = ZEBRA_ROUTE_RIPNG; - else if (strncmp (argv[0], "bgp", 3) == 0) - type = ZEBRA_ROUTE_BGP; + int type; + + type = proto_redistnum(AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_OSPF6) + return CMD_WARNING; ospf6_asbr_redistribute_unset (type); ospf6_asbr_routemap_unset (type); @@ -646,29 +635,18 @@ DEFUN (ospf6_redistribute, DEFUN (ospf6_redistribute_routemap, ospf6_redistribute_routemap_cmd, - "redistribute (static|kernel|connected|ripng|bgp) route-map WORD", + "redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD", "Redistribute\n" - "Static routes\n" - "Kernel route\n" - "Connected route\n" - "RIPng route\n" - "BGP route\n" + QUAGGA_REDIST_HELP_STR_OSPF6D "Route map reference\n" "Route map name\n" ) { - int type = 0; - - if (strncmp (argv[0], "sta", 3) == 0) - type = ZEBRA_ROUTE_STATIC; - else if (strncmp (argv[0], "ker", 3) == 0) - type = ZEBRA_ROUTE_KERNEL; - else if (strncmp (argv[0], "con", 3) == 0) - type = ZEBRA_ROUTE_CONNECT; - else if (strncmp (argv[0], "rip", 3) == 0) - type = ZEBRA_ROUTE_RIPNG; - else if (strncmp (argv[0], "bgp", 3) == 0) - type = ZEBRA_ROUTE_BGP; + int type; + + type = proto_redistnum(AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_OSPF6) + return CMD_WARNING; ospf6_asbr_redistribute_unset (type); ospf6_asbr_routemap_set (type, argv[1]); @@ -678,28 +656,17 @@ DEFUN (ospf6_redistribute_routemap, DEFUN (no_ospf6_redistribute, no_ospf6_redistribute_cmd, - "no redistribute (static|kernel|connected|ripng|bgp)", + "no redistribute " QUAGGA_REDIST_STR_OSPF6D, NO_STR "Redistribute\n" - "Static route\n" - "Kernel route\n" - "Connected route\n" - "RIPng route\n" - "BGP route\n" + QUAGGA_REDIST_HELP_STR_OSPF6D ) { - int type = 0; - - if (strncmp (argv[0], "sta", 3) == 0) - type = ZEBRA_ROUTE_STATIC; - else if (strncmp (argv[0], "ker", 3) == 0) - type = ZEBRA_ROUTE_KERNEL; - else if (strncmp (argv[0], "con", 3) == 0) - type = ZEBRA_ROUTE_CONNECT; - else if (strncmp (argv[0], "rip", 3) == 0) - type = ZEBRA_ROUTE_RIPNG; - else if (strncmp (argv[0], "bgp", 3) == 0) - type = ZEBRA_ROUTE_BGP; + int type; + + type = proto_redistnum(AFI_IP6, argv[0]); + if (type < 0 || type == ZEBRA_ROUTE_OSPF6) + return CMD_WARNING; ospf6_asbr_redistribute_unset (type); ospf6_asbr_routemap_unset (type); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 955a8227..b1526c33 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -92,29 +92,6 @@ ospf_str2area_id (const char *str, struct in_addr *area_id, int *format) } -static int -str2distribute_source (const char *str, int *source) -{ - /* Sanity check. */ - if (str == NULL) - return 0; - - if (strncmp (str, "k", 1) == 0) - *source = ZEBRA_ROUTE_KERNEL; - else if (strncmp (str, "c", 1) == 0) - *source = ZEBRA_ROUTE_CONNECT; - else if (strncmp (str, "s", 1) == 0) - *source = ZEBRA_ROUTE_STATIC; - else if (strncmp (str, "r", 1) == 0) - *source = ZEBRA_ROUTE_RIP; - else if (strncmp (str, "b", 1) == 0) - *source = ZEBRA_ROUTE_BGP; - else - return 0; - - return 1; -} - static int str2metric (const char *str, int *metric) { @@ -5818,7 +5795,8 @@ DEFUN (ospf_redistribute_source_metric_type, int metric = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -5879,7 +5857,8 @@ DEFUN (ospf_redistribute_source_type_metric, int metric = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -5943,7 +5922,8 @@ DEFUN (ospf_redistribute_source_metric_routemap, int metric = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -5976,7 +5956,8 @@ DEFUN (ospf_redistribute_source_type_routemap, int type = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -6004,7 +5985,8 @@ DEFUN (ospf_redistribute_source_routemap, int source; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; if (argc == 2) @@ -6025,7 +6007,8 @@ DEFUN (no_ospf_redistribute_source, struct ospf *ospf = vty->index; int source; - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; ospf_routemap_unset (ospf, source); @@ -6044,7 +6027,8 @@ DEFUN (ospf_distribute_list_out, int source; /* Get distribute source. */ - if (!str2distribute_source (argv[1], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; return ospf_distribute_list_out_set (ospf, source, argv[0]); @@ -6062,7 +6046,8 @@ DEFUN (no_ospf_distribute_list_out, struct ospf *ospf = vty->index; int source; - if (!str2distribute_source (argv[1], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; return ospf_distribute_list_out_unset (ospf, source, argv[0]); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index ecb5d10a..05485a13 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -802,10 +802,6 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib) } } -#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, " \ - "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, " \ - "> - selected route, * - FIB route%s%s" - DEFUN (show_ip_route, show_ip_route_cmd, "show ip route", @@ -828,8 +824,7 @@ DEFUN (show_ip_route, { if (first) { - vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE, - VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V4_HEADER); first = 0; } vty_show_ip_route (vty, rn, rib); @@ -871,8 +866,7 @@ DEFUN (show_ip_route_prefix_longer, { if (first) { - vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, - VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V4_HEADER); first = 0; } vty_show_ip_route (vty, rn, rib); @@ -910,8 +904,7 @@ DEFUN (show_ip_route_supernets, { if (first) { - vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, - VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V4_HEADER); first = 0; } vty_show_ip_route (vty, rn, rib); @@ -922,17 +915,11 @@ DEFUN (show_ip_route_supernets, DEFUN (show_ip_route_protocol, show_ip_route_protocol_cmd, - "show ip route (bgp|connected|isis|kernel|ospf|rip|static)", + "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA, SHOW_STR IP_STR "IP routing table\n" - "Border Gateway Protocol (BGP)\n" - "Connected\n" - "ISO IS-IS (ISIS)\n" - "Kernel\n" - "Open Shortest Path First (OSPF)\n" - "Routing Information Protocol (RIP)\n" - "Static routes\n") + QUAGGA_IP_REDIST_HELP_STR_ZEBRA) { int type; struct route_table *table; @@ -940,21 +927,8 @@ DEFUN (show_ip_route_protocol, struct rib *rib; int first = 1; - if (strncmp (argv[0], "b", 1) == 0) - type = ZEBRA_ROUTE_BGP; - else if (strncmp (argv[0], "c", 1) == 0) - type = ZEBRA_ROUTE_CONNECT; - else if (strncmp (argv[0], "k", 1) ==0) - type = ZEBRA_ROUTE_KERNEL; - else if (strncmp (argv[0], "o", 1) == 0) - type = ZEBRA_ROUTE_OSPF; - else if (strncmp (argv[0], "i", 1) == 0) - type = ZEBRA_ROUTE_ISIS; - else if (strncmp (argv[0], "r", 1) == 0) - type = ZEBRA_ROUTE_RIP; - else if (strncmp (argv[0], "s", 1) == 0) - type = ZEBRA_ROUTE_STATIC; - else + type = proto_redistnum (AFI_IP, argv[0]); + if (type < 0) { vty_out (vty, "Unknown route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -971,8 +945,7 @@ DEFUN (show_ip_route_protocol, { if (first) { - vty_out (vty, SHOW_ROUTE_V4_HEADER, - VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V4_HEADER); first = 0; } vty_show_ip_route (vty, rn, rib); @@ -1766,8 +1739,6 @@ vty_show_ipv6_route (struct vty *vty, struct route_node *rn, } } -#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s I - ISIS, B - BGP, * - FIB route.%s%s" - DEFUN (show_ipv6_route, show_ipv6_route_cmd, "show ipv6 route", @@ -1790,7 +1761,7 @@ DEFUN (show_ipv6_route, { if (first) { - vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V6_HEADER); first = 0; } vty_show_ipv6_route (vty, rn, rib); @@ -1832,7 +1803,7 @@ DEFUN (show_ipv6_route_prefix_longer, { if (first) { - vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V6_HEADER); first = 0; } vty_show_ipv6_route (vty, rn, rib); @@ -1842,17 +1813,11 @@ DEFUN (show_ipv6_route_prefix_longer, DEFUN (show_ipv6_route_protocol, show_ipv6_route_protocol_cmd, - "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|static)", + "show ipv6 route " QUAGGA_IP6_REDIST_STR_ZEBRA, SHOW_STR IP_STR "IP routing table\n" - "Border Gateway Protocol (BGP)\n" - "Connected\n" - "ISO IS-IS (ISIS)\n" - "Kernel\n" - "Open Shortest Path First (OSPFv3)\n" - "Routing Information Protocol (RIPng)\n" - "Static routes\n") + QUAGGA_IP6_REDIST_HELP_STR_ZEBRA) { int type; struct route_table *table; @@ -1860,21 +1825,8 @@ DEFUN (show_ipv6_route_protocol, struct rib *rib; int first = 1; - if (strncmp (argv[0], "b", 1) == 0) - type = ZEBRA_ROUTE_BGP; - else if (strncmp (argv[0], "c", 1) == 0) - type = ZEBRA_ROUTE_CONNECT; - else if (strncmp (argv[0], "k", 1) ==0) - type = ZEBRA_ROUTE_KERNEL; - else if (strncmp (argv[0], "o", 1) == 0) - type = ZEBRA_ROUTE_OSPF6; - else if (strncmp (argv[0], "i", 1) == 0) - type = ZEBRA_ROUTE_ISIS; - else if (strncmp (argv[0], "r", 1) == 0) - type = ZEBRA_ROUTE_RIPNG; - else if (strncmp (argv[0], "s", 1) == 0) - type = ZEBRA_ROUTE_STATIC; - else + type = proto_redistnum (AFI_IP6, argv[0]); + if (type < 0) { vty_out (vty, "Unknown route type%s", VTY_NEWLINE); return CMD_WARNING; @@ -1891,7 +1843,7 @@ DEFUN (show_ipv6_route_protocol, { if (first) { - vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, SHOW_ROUTE_V6_HEADER); first = 0; } vty_show_ipv6_route (vty, rn, rib); -- cgit v1.2.1 From 7d3d2de4657a080275a705fbf3bd21a484cb3e4b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 4 Oct 2009 16:21:49 +0200 Subject: lib: add sockopt helper for setting IPV6_V6ONLY and use it getaddrinfo returns a list of socket parameters for listening. it will contain both IPv4 and IPv6 listening sockets. unless we use IPV6_V6ONLY on the IPv6 ones, only the socket listed first will work. if the IPv4 one came first, the IPv6 one would get an "Address in use" error. this functionality was already present for bgpd and its listening sockets. as it is needed for vtys as well, make it a common helper. --- bgpd/bgp_network.c | 9 +-------- lib/sockunion.c | 24 ++++++++++++++++++++++++ lib/sockunion.h | 1 + lib/vty.c | 1 + 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index bd2e2d68..b5c4c602 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -387,14 +387,7 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen) # endif #endif -#ifdef IPV6_V6ONLY - /* Want only IPV6 on ipv6 socket (not mapped addresses) */ - if (sa->sa_family == AF_INET6) { - int on = 1; - setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, - (void *) &on, sizeof (on)); - } -#endif + sockopt_v6only (sa->sa_family, sock); ret = bind (sock, sa, salen); en = errno; diff --git a/lib/sockunion.c b/lib/sockunion.c index 6a40f332..d1f6d80b 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -527,6 +527,30 @@ sockopt_ttl (int family, int sock, int ttl) return 0; } +int +sockopt_v6only (int family, int sock) +{ + int ret, on = 1; + +#ifdef HAVE_IPV6 +#ifdef IPV6_V6ONLY + if (family == AF_INET6) + { + ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, + (void *) &on, sizeof (int)); + if (ret < 0) + { + zlog (NULL, LOG_WARNING, "can't set sockopt IPV6_V6ONLY " + "to socket %d", sock); + return -1; + } + return 0; + } +#endif /* IPV6_V6ONLY */ +#endif /* HAVE_IPV6 */ + return 0; +} + /* 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..db145cf2 100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h @@ -99,6 +99,7 @@ extern int sockunion_accept (int sock, union sockunion *); extern int sockunion_stream_socket (union sockunion *); extern int sockopt_reuseaddr (int); extern int sockopt_reuseport (int); +extern int sockopt_v6only (int family, int sock); extern int sockunion_bind (int sock, union sockunion *, unsigned short, union sockunion *); extern int sockopt_ttl (int family, int sock, int ttl); diff --git a/lib/vty.c b/lib/vty.c index bd1dbac0..e403159b 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1816,6 +1816,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port) if (sock < 0) continue; + sockopt_v6only (ainfo->ai_family, sock); sockopt_reuseaddr (sock); sockopt_reuseport (sock); -- cgit v1.2.1 From bb6ef3e270f9ae53ac46461962500cf94ecdff08 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 14 Oct 2011 20:56:19 +0400 Subject: lib: spelling --- lib/distribute.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/distribute.c b/lib/distribute.c index 242a225c..7f84b80e 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -412,7 +412,7 @@ ALIAS (distribute_list, "Filter outgoing routing updates\n" "Interface name\n") -DEFUN (no_districute_list, no_distribute_list_cmd, +DEFUN (no_distribute_list, no_distribute_list_cmd, "no distribute-list WORD (in|out) WORD", NO_STR "Filter networks in routing updates\n" @@ -444,7 +444,7 @@ DEFUN (no_districute_list, no_distribute_list_cmd, return CMD_SUCCESS; } -ALIAS (no_districute_list, no_ipv6_distribute_list_cmd, +ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd, "no distribute-list WORD (in|out) WORD", NO_STR "Filter networks in routing updates\n" @@ -453,7 +453,7 @@ ALIAS (no_districute_list, no_ipv6_distribute_list_cmd, "Filter outgoing routing updates\n" "Interface name\n") -DEFUN (districute_list_prefix_all, +DEFUN (distribute_list_prefix_all, distribute_list_prefix_all_cmd, "distribute-list prefix WORD (in|out)", "Filter networks in routing updates\n" @@ -483,7 +483,7 @@ DEFUN (districute_list_prefix_all, return CMD_SUCCESS; } -ALIAS (districute_list_prefix_all, +ALIAS (distribute_list_prefix_all, ipv6_distribute_list_prefix_all_cmd, "distribute-list prefix WORD (in|out)", "Filter networks in routing updates\n" @@ -492,7 +492,7 @@ ALIAS (districute_list_prefix_all, "Filter incoming routing updates\n" "Filter outgoing routing updates\n") -DEFUN (no_districute_list_prefix_all, +DEFUN (no_distribute_list_prefix_all, no_distribute_list_prefix_all_cmd, "no distribute-list prefix WORD (in|out)", NO_STR @@ -526,7 +526,7 @@ DEFUN (no_districute_list_prefix_all, return CMD_SUCCESS; } -ALIAS (no_districute_list_prefix_all, +ALIAS (no_distribute_list_prefix_all, no_ipv6_distribute_list_prefix_all_cmd, "no distribute-list prefix WORD (in|out)", NO_STR @@ -536,7 +536,7 @@ ALIAS (no_districute_list_prefix_all, "Filter incoming routing updates\n" "Filter outgoing routing updates\n") -DEFUN (districute_list_prefix, distribute_list_prefix_cmd, +DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, "distribute-list prefix WORD (in|out) WORD", "Filter networks in routing updates\n" "Filter prefixes in routing updates\n" @@ -566,7 +566,7 @@ DEFUN (districute_list_prefix, distribute_list_prefix_cmd, return CMD_SUCCESS; } -ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd, +ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd, "distribute-list prefix WORD (in|out) WORD", "Filter networks in routing updates\n" "Filter prefixes in routing updates\n" @@ -575,7 +575,7 @@ ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd, "Filter outgoing routing updates\n" "Interface name\n") -DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd, +DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd, "no distribute-list prefix WORD (in|out) WORD", NO_STR "Filter networks in routing updates\n" @@ -609,7 +609,7 @@ DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd, return CMD_SUCCESS; } -ALIAS (no_districute_list_prefix, no_ipv6_distribute_list_prefix_cmd, +ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd, "no distribute-list prefix WORD (in|out) WORD", NO_STR "Filter networks in routing updates\n" -- cgit v1.2.1 From 8fee927850e9011b3bf46f2a8a0d54521d00a807 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 14 Oct 2011 20:59:43 +0400 Subject: lib: address -Wunused-but-set-variable * if.c * if_dump(): 'node', 'c' * distribute.c * distribute_list_all(): 'dist' * distribute_list(): 'dist' * districute_list_prefix_all(): 'dist' * if_rmap.c * if_rmap(): 'if_rmap' * vty.c * vty_accept(): 'vty' --- lib/distribute.c | 12 ++++-------- lib/if.c | 6 ------ lib/if_rmap.c | 3 +-- lib/vty.c | 3 +-- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/lib/distribute.c b/lib/distribute.c index 7f84b80e..056cd401 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -304,7 +304,6 @@ DEFUN (distribute_list_all, "Filter outgoing routing updates\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -319,7 +318,7 @@ DEFUN (distribute_list_all, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_set (NULL, type, argv[0]); + distribute_list_set (NULL, type, argv[0]); return CMD_SUCCESS; } @@ -384,7 +383,6 @@ DEFUN (distribute_list, "Interface name\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -398,7 +396,7 @@ DEFUN (distribute_list, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_set (argv[2], type, argv[0]); + distribute_list_set (argv[2], type, argv[0]); return CMD_SUCCESS; } @@ -463,7 +461,6 @@ DEFUN (distribute_list_prefix_all, "Filter outgoing routing updates\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -478,7 +475,7 @@ DEFUN (distribute_list_prefix_all, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_prefix_set (NULL, type, argv[0]); + distribute_list_prefix_set (NULL, type, argv[0]); return CMD_SUCCESS; } @@ -546,7 +543,6 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, "Interface name\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -561,7 +557,7 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_prefix_set (argv[2], type, argv[0]); + distribute_list_prefix_set (argv[2], type, argv[0]); return CMD_SUCCESS; } diff --git a/lib/if.c b/lib/if.c index d14cfb93..41115b0f 100644 --- a/lib/if.c +++ b/lib/if.c @@ -426,9 +426,6 @@ if_flag_dump (unsigned long flag) static void if_dump (const struct interface *ifp) { - struct listnode *node; - struct connected *c; - zlog_info ("Interface %s index %d metric %d mtu %d " #ifdef HAVE_IPV6 "mtu6 %d " @@ -439,9 +436,6 @@ if_dump (const struct interface *ifp) ifp->mtu6, #endif /* HAVE_IPV6 */ if_flag_dump (ifp->flags)); - - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c)) - ; } /* Interface printing for all interface. */ diff --git a/lib/if_rmap.c b/lib/if_rmap.c index ddc62fd5..b49d2669 100644 --- a/lib/if_rmap.c +++ b/lib/if_rmap.c @@ -212,7 +212,6 @@ DEFUN (if_rmap, "Route map interface name\n") { enum if_rmap_type type; - struct if_rmap *if_rmap; if (strncmp (argv[1], "i", 1) == 0) type = IF_RMAP_IN; @@ -224,7 +223,7 @@ DEFUN (if_rmap, return CMD_WARNING; } - if_rmap = if_rmap_set (argv[2], type, argv[0]); + if_rmap_set (argv[2], type, argv[0]); return CMD_SUCCESS; } diff --git a/lib/vty.c b/lib/vty.c index e403159b..4fed2711 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1685,7 +1685,6 @@ static int vty_accept (struct thread *thread) { int vty_sock; - struct vty *vty; union sockunion su; int ret; unsigned int on; @@ -1770,7 +1769,7 @@ vty_accept (struct thread *thread) if (bufp) XFREE (MTYPE_TMP, bufp); - vty = vty_create (vty_sock, &su); + vty_create (vty_sock, &su); return 0; } -- cgit v1.2.1 From ed72156c9d4512217f5c80b8e20e4de024246502 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 14 Oct 2011 21:59:58 +0400 Subject: ospf6d: decode message type with LOOKUP() * ospf6_message.h * OSPF6_MESSAGE_TYPE_CANONICAL(): dismiss * OSPF6_MESSAGE_TYPE_NAME(): dismiss * ospf6_message.c * ospf6_message_type_str: rewrite as a message list, add max value * ospf6_packet_examin(): update to use LOOKUP() * ospf6_receive(): idem * ospf6_send(): idem --- ospf6d/ospf6_message.c | 24 ++++++++++++++++-------- ospf6d/ospf6_message.h | 7 ------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 5760874d..8179fc14 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -50,8 +50,16 @@ #include unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0}; -const char *ospf6_message_type_str[] = - { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" }; +static const struct message ospf6_message_type_str [] = +{ + { OSPF6_MESSAGE_TYPE_HELLO, "Hello" }, + { OSPF6_MESSAGE_TYPE_DBDESC, "DbDesc" }, + { OSPF6_MESSAGE_TYPE_LSREQ, "LSReq" }, + { OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate" }, + { OSPF6_MESSAGE_TYPE_LSACK, "LSAck" }, +}; +static const size_t ospf6_message_type_str_max = + sizeof (ospf6_message_type_str) / sizeof (ospf6_message_type_str[0]); /* Minimum (besides the standard OSPF packet header) lengths for OSPF packets of particular types, offset is the "type" field. */ @@ -1194,7 +1202,7 @@ ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) { if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) zlog_debug ("%s: undersized (%u B) %s packet", __func__, - bytesonwire, ospf6_message_type_str[oh->type]); + bytesonwire, LOOKUP (ospf6_message_type_str, oh->type)); return MSG_NG; } /* type-specific deeper validation */ @@ -1207,7 +1215,7 @@ ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) return MSG_OK; if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) zlog_debug ("%s: alignment error in %s packet", - __func__, ospf6_message_type_str[oh->type]); + __func__, LOOKUP (ospf6_message_type_str, oh->type)); return MSG_NG; case OSPF6_MESSAGE_TYPE_DBDESC: /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed @@ -1226,7 +1234,7 @@ ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) return MSG_OK; if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) zlog_debug ("%s: alignment error in %s packet", - __func__, ospf6_message_type_str[oh->type]); + __func__, LOOKUP (ospf6_message_type_str, oh->type)); return MSG_NG; case OSPF6_MESSAGE_TYPE_LSUPDATE: /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed @@ -1256,7 +1264,7 @@ ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) return MSG_NG; } if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: anomaly in %s packet", __func__, ospf6_message_type_str[oh->type]); + zlog_debug ("%s: anomaly in %s packet", __func__, LOOKUP (ospf6_message_type_str, oh->type)); return test; } @@ -1559,7 +1567,7 @@ ospf6_receive (struct thread *thread) inet_ntop (AF_INET6, &src, srcname, sizeof (srcname)); inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname)); zlog_debug ("%s received on %s", - OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name); + LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name); zlog_debug (" src: %s", srcname); zlog_debug (" dst: %s", dstname); @@ -1647,7 +1655,7 @@ ospf6_send (struct in6_addr *src, struct in6_addr *dst, else memset (srcname, 0, sizeof (srcname)); zlog_debug ("%s send on %s", - OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name); + LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name); zlog_debug (" src: %s", srcname); zlog_debug (" dst: %s", dstname); diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h index b24d2e62..87a7cfeb 100644 --- a/ospf6d/ospf6_message.h +++ b/ospf6d/ospf6_message.h @@ -44,13 +44,6 @@ extern unsigned char conf_debug_ospf6_message[]; #define OSPF6_MESSAGE_TYPE_LSACK 0x5 /* Flooding acknowledgment */ #define OSPF6_MESSAGE_TYPE_ALL 0x6 /* For debug option */ -#define OSPF6_MESSAGE_TYPE_CANONICAL(T) \ - ((T) > OSPF6_MESSAGE_TYPE_LSACK ? OSPF6_MESSAGE_TYPE_UNKNOWN : (T)) - -extern const char *ospf6_message_type_str[]; -#define OSPF6_MESSAGE_TYPE_NAME(T) \ - (ospf6_message_type_str[ OSPF6_MESSAGE_TYPE_CANONICAL (T) ]) - /* OSPFv3 packet header */ #define OSPF6_HEADER_SIZE 16U struct ospf6_header -- cgit v1.2.1 From ba1a944aa7adffd9194ef0ad61649fe3e02b0f38 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 10 Dec 2009 17:19:09 +0000 Subject: vty_serv_sock_family unused If the vty_serv_sock_addrinfo is being used, then vty_serv_sock_family is unsed. Fix by adjusting ifdef/else/endif --- lib/vty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/vty.c b/lib/vty.c index 4fed2711..83bd6785 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1839,7 +1839,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port) freeaddrinfo (ainfo_save); } -#endif /* HAVE_IPV6 && ! NRL */ +#else /* HAVE_IPV6 && ! NRL */ /* Make vty server socket. */ static void @@ -1905,6 +1905,7 @@ vty_serv_sock_family (const char* addr, unsigned short port, int family) /* Add vty server event. */ vty_event (VTY_SERV, accept_sock, NULL); } +#endif /* HAVE_IPV6 && ! NRL */ #ifdef VTYSH /* For sockaddr_un. */ -- cgit v1.2.1 From 49ff274c29eaa45ae85766e62dab32faea7f32b8 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 17 Oct 2011 21:11:10 +0400 Subject: lib: make masklen2ip6() safer and faster --- lib/prefix.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- lib/prefix.h | 2 +- 2 files changed, 136 insertions(+), 17 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 4be3ba20..075c9dab 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -103,6 +103,138 @@ static const u_int32_t maskbytes_network[] = 0xfeffffff, /* /31 255.255.255.254 */ 0xffffffff /* /32 255.255.255.255 */ }; +static const struct in6_addr maskbytes6[] = +{ + /* /0 */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /1 */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /2 */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /3 */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /4 */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /5 */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /6 */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /7 */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /8 */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /9 */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /10 */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /11 */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /12 */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /13 */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /14 */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /15 */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /16 */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /17 */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /18 */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /19 */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /20 */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /21 */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /22 */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /23 */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /24 */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /25 */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /26 */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /27 */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /28 */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /29 */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /30 */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /31 */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /32 */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /33 */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /34 */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /35 */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /36 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /37 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /38 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /39 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /40 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /41 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /42 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /43 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /44 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /45 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /46 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /47 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /48 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /49 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /50 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /51 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /52 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /53 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /54 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /55 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /56 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /57 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /58 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /59 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /60 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /61 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /62 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /63 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /64 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /65 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /66 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /67 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /68 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /69 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /70 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /71 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /72 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /73 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /74 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /75 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /76 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /77 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /78 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /79 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /80 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /81 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /82 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /83 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /84 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /85 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /86 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /87 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /88 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + /* /89 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } }, + /* /90 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } }, + /* /91 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } }, + /* /92 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } }, + /* /93 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } }, + /* /94 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } }, + /* /95 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } }, + /* /96 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + /* /97 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } }, + /* /98 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } }, + /* /99 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } }, + /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } }, + /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } }, + /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } }, + /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } }, + /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } }, + /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } }, + /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } }, + /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } }, + /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } }, + /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } }, + /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } }, + /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } }, + /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } }, + /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } }, + /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } }, + /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } }, + /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } }, + /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } }, + /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } }, + /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } }, + /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } }, + /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } }, + /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } }, + /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } }, + /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } }, + /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } }, + /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } }, + /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } } +}; /* Number of bits in prefix type. */ #ifndef PNBBY @@ -534,23 +666,10 @@ ip6_masklen (struct in6_addr netmask) } void -masklen2ip6 (int masklen, struct in6_addr *netmask) +masklen2ip6 (const int masklen, struct in6_addr *netmask) { - unsigned char *pnt; - int bit; - int offset; - - memset (netmask, 0, sizeof (struct in6_addr)); - pnt = (unsigned char *) netmask; - - offset = masklen / 8; - bit = masklen % 8; - - while (offset--) - *pnt++ = 0xff; - - if (bit) - *pnt = maskbit[bit]; + assert (masklen >=0 && masklen <= 128); + memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr)); } void diff --git a/lib/prefix.h b/lib/prefix.h index 675f94d4..12c0d07e 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -199,7 +199,7 @@ extern void apply_mask_ipv6 (struct prefix_ipv6 *); *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC)); extern int ip6_masklen (struct in6_addr); -extern void masklen2ip6 (int, struct in6_addr *); +extern void masklen2ip6 (const int, struct in6_addr *); extern void str2in6_addr (const char *, struct in6_addr *); extern const char *inet6_ntoa (struct in6_addr); -- cgit v1.2.1 From 3062d2dab6e8bea9003d67a05d1e018a927d6f1d Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 18 Oct 2011 15:27:21 +0400 Subject: bgpd: fix error message in bgp_attr_aspath() --- bgpd/bgp_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index dae895d7..55691fda 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -813,7 +813,7 @@ bgp_attr_aspath (struct peer *peer, bgp_size_t length, 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) ; + CHECK_FLAG (require, BGP_ATTR_FLAG_OPTIONAL) ? "" : "not ", flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, -- cgit v1.2.1 From ed7a62efea6d957b0c5f60ec52644bba062f6c29 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 18 Oct 2011 18:33:53 +0400 Subject: lib: optimize apply_mask_ipv4() --- lib/prefix.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 075c9dab..1ddbbbe7 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -545,27 +545,12 @@ ip_masklen (struct in_addr netmask) return len; } -/* Apply mask to IPv4 prefix. */ +/* Apply mask to IPv4 prefix (network byte order). */ void apply_mask_ipv4 (struct prefix_ipv4 *p) { - u_char *pnt; - int index; - int offset; - - index = p->prefixlen / 8; - - if (index < 4) - { - pnt = (u_char *) &p->prefix; - offset = p->prefixlen % 8; - - pnt[index] &= maskbit[offset]; - index++; - - while (index < 4) - pnt[index++] = 0; - } + assert (p->prefixlen >= 0 && p->prefixlen <= IPV4_MAX_BITLEN); + p->prefix.s_addr &= maskbytes_network[p->prefixlen]; } /* If prefix is 0.0.0.0/0 then return 1 else return 0. */ -- cgit v1.2.1 From c6cb2d9151fc14f9c2b1b7618695874cc8d97286 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 18 Oct 2011 22:02:52 +0400 Subject: lib: optimize apply_mask_ipv6() --- lib/prefix.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 1ddbbbe7..c8fd0bd8 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -660,23 +660,13 @@ masklen2ip6 (const int masklen, struct in6_addr *netmask) void apply_mask_ipv6 (struct prefix_ipv6 *p) { - u_char *pnt; - int index; - int offset; - - index = p->prefixlen / 8; - - if (index < 16) - { - pnt = (u_char *) &p->prefix; - offset = p->prefixlen % 8; - - pnt[index] &= maskbit[offset]; - index++; - - while (index < 16) - pnt[index++] = 0; - } + assert (p->prefixlen >= 0 && p->prefixlen <= IPV6_MAX_BITLEN); + u_int32_t *addr_word = (u_int32_t *) &p->prefix; + u_int32_t *mask_word = (u_int32_t *) (maskbytes6 + p->prefixlen); + *addr_word++ &= *mask_word++; + *addr_word++ &= *mask_word++; + *addr_word++ &= *mask_word++; + *addr_word &= *mask_word; } void -- cgit v1.2.1 From 12da1a188a5e5bfdfecb98c48ecca48ed38e2d89 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 22 Oct 2011 22:11:31 +0400 Subject: bgpd: check AGGREGATOR attr flags (BZ#678) * bgp_attr.c * bgp_attr_aggregator(): check Optional/Transitive flag bits --- bgpd/bgp_attr.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 55691fda..7c94f7e0 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1103,6 +1103,27 @@ bgp_attr_aggregator (struct peer *peer, bgp_size_t length, bgp_size_t total; total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Flags check. */ + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) + { + zlog (peer->log, LOG_ERR, + "AGGREGATOR attribute must be flagged as \"optional\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } + if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + { + zlog (peer->log, LOG_ERR, + "AGGREGATOR attribute must be flagged as \"transitive\" (%u)", flag); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, + startp, total); + return -1; + } /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */ if ( CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV ) ) wantedlen = 8; -- cgit v1.2.1 From 5c8d16fd853c29856e45709424701c93ef626f2f Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 22 Oct 2011 22:18:55 +0400 Subject: ospfd: spelling/format fix --- ospfd/ospf_lsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index e708d5e2..9968d273 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -3684,7 +3684,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) lsa->refresh_list = index; if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): " - "setting refresh_list on lsa %p (slod %d)", + "setting refresh_list on lsa %p (index %u)", inet_ntoa (lsa->data->id), lsa, index); } } -- cgit v1.2.1 From 26f5e782ef43dbe4496d795d70c490b42da31c6a Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 23 Oct 2011 22:32:44 +0400 Subject: bgpd: rewrite attr flag error logging * bgp_attr.c * attr_flag_str: new message list * bgp_attr_flags_diagnose(): new function, implements previously added error logging in a generic way * bgp_attr_origin(): use bgp_attr_flags_diagnose() * bgp_attr_nexthop(): ditto * bgp_attr_med(): ditto * bgp_attr_local_pref(): ditto * bgp_attr_atomic(): ditto * bgp_attr_originator_id(): ditto * bgp_attr_cluster_list(): ditto * bgp_mp_reach_parse(): ditto * bgp_mp_unreach_parse(): ditto --- bgpd/bgp_attr.c | 108 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 7c94f7e0..829b0176 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -62,6 +62,17 @@ static const struct message attr_str [] = { BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT" }, }; static const int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]); + +static const struct message attr_flag_str[] = +{ + { BGP_ATTR_FLAG_OPTIONAL, "Optional" }, + { BGP_ATTR_FLAG_TRANS, "Transitive" }, + { BGP_ATTR_FLAG_PARTIAL, "Partial" }, + /* bgp_attr_flags_diagnose() relies on this bit being last in this list */ + { BGP_ATTR_FLAG_EXTLEN, "Extended Length" }, +}; +static const size_t attr_flag_str_max = + sizeof (attr_flag_str) / sizeof (attr_flag_str[0]); static struct hash *cluster_hash; @@ -697,6 +708,40 @@ bgp_attr_flush (struct attr *attr) } } +/* Find out what is wrong with the path attribute flag bits and log the error. + "Flag bits" here stand for Optional, Transitive and Partial, but not for + Extended Length. Checking O/T/P bits at once implies, that the attribute + being diagnosed is defined by RFC as either a "well-known" or an "optional, + non-transitive" attribute. */ +static void +bgp_attr_flags_diagnose +( + struct peer * peer, + const u_int8_t attr_code, + u_int8_t desired_flags, /* how RFC says it must be */ + u_int8_t real_flags /* on wire */ +) +{ + u_char seen = 0, i; + + desired_flags &= ~BGP_ATTR_FLAG_EXTLEN; + real_flags &= ~BGP_ATTR_FLAG_EXTLEN; + for (i = 0; i <= 2; i++) /* O,T,P, but not E */ + if + ( + CHECK_FLAG (desired_flags, attr_flag_str[i].key) != + CHECK_FLAG (real_flags, attr_flag_str[i].key) + ) + { + zlog (peer->log, LOG_ERR, "%s attribute must%s be flagged as \"%s\"", + LOOKUP (attr_str, attr_code), + CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not", + attr_flag_str[i].str); + seen = 1; + } + assert (seen); +} + /* Get origin attribute of the update message. */ static int bgp_attr_origin (struct peer *peer, bgp_size_t length, @@ -714,12 +759,7 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length, attribute (type, length and value). */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag); - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "ORIGIN attribute must be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "ORIGIN attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_ORIGIN, BGP_ATTR_FLAG_TRANS, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -917,12 +957,7 @@ bgp_attr_nexthop (struct peer *peer, bgp_size_t length, /* Flags check. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must not be flagged as \"optional\" (%u)", flag); - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_NEXT_HOP, BGP_ATTR_FLAG_TRANS, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -977,12 +1012,7 @@ bgp_attr_med (struct peer *peer, bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must be flagged as \"optional\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must not be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_MULTI_EXIT_DISC, BGP_ATTR_FLAG_OPTIONAL, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -1018,12 +1048,7 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must not be flagged as \"optional\" (%u)", flag); - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_LOCAL_PREF, BGP_ATTR_FLAG_TRANS, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -1066,12 +1091,7 @@ bgp_attr_atomic (struct peer *peer, bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS) { - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must not be flagged as \"optional\" (%u)", flag); - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_ATOMIC_AGGREGATE, BGP_ATTR_FLAG_TRANS, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -1325,12 +1345,7 @@ bgp_attr_originator_id (struct peer *peer, bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must be flagged as \"optional\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must not be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_ORIGINATOR_ID, BGP_ATTR_FLAG_OPTIONAL, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -1364,12 +1379,7 @@ bgp_attr_cluster_list (struct peer *peer, bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must be flagged as \"optional\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must not be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_CLUSTER_LIST, BGP_ATTR_FLAG_OPTIONAL, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -1412,12 +1422,7 @@ bgp_mp_reach_parse (struct peer *peer, const bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must be flagged as \"optional\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must not be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_MP_REACH_NLRI, BGP_ATTR_FLAG_OPTIONAL, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } @@ -1559,12 +1564,7 @@ bgp_mp_unreach_parse (struct peer *peer, const bgp_size_t length, /* Flag checks. */ if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL) { - if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) - zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must be flagged as \"optional\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) - zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must not be flagged as \"transitive\" (%u)", flag); - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) - zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must not be flagged as \"partial\" (%u)", flag); + bgp_attr_flags_diagnose (peer, BGP_ATTR_MP_UNREACH_NLRI, BGP_ATTR_FLAG_OPTIONAL, flag); bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); return -1; } -- cgit v1.2.1 From f6247bf278861c41a5cb61639176d5ed1301e81e Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 24 Oct 2011 18:17:09 +0400 Subject: ospfd: use IS_LSA_SELF() where appropriate --- ospfd/ospf_lsa.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 9968d273..132a281c 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2913,7 +2913,7 @@ ospf_maxage_lsa_remover (struct thread *thread) } /* Remove LSA from the LSDB */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)) + if (IS_LSA_SELF (lsa)) if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ", lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa); @@ -3457,7 +3457,7 @@ ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa) /* This LSA is already checked. */ if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED)) - return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); + return IS_LSA_SELF (lsa); /* Make sure LSA is self-checked. */ SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED); @@ -3482,11 +3482,11 @@ ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa) { /* to make it easier later */ SET_FLAG (lsa->flags, OSPF_LSA_SELF); - return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); + return IS_LSA_SELF (lsa); } } - return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); + return IS_LSA_SELF (lsa); } /* Get unique Link State ID. */ @@ -3607,7 +3607,7 @@ static void ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) { struct external_info *ei; - assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); + assert (IS_LSA_SELF (lsa)); switch (lsa->data->type) { @@ -3650,7 +3650,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) { u_int16_t index, current_index; - assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); + assert (IS_LSA_SELF (lsa)); if (lsa->refresh_list < 0) { @@ -3692,7 +3692,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 (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); + assert (IS_LSA_SELF (lsa)); if (lsa->refresh_list >= 0) { struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list]; -- cgit v1.2.1 From d3962ba7c75db6aeb926bf909e643cef12a843ef Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 24 Oct 2011 18:45:05 +0400 Subject: lib: use prefix bit length macros --- lib/prefix.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index c8fd0bd8..54b9bc8a 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -371,8 +371,8 @@ prefix_cmp (const struct prefix *p1, const struct prefix *p2) if (p1->family != p2->family || p1->prefixlen != p2->prefixlen) return 1; - offset = p1->prefixlen / 8; - shift = p1->prefixlen % 8; + offset = p1->prefixlen / PNBBY; + shift = p1->prefixlen % PNBBY; if (shift) if (maskbit[shift] & (pp1[offset] ^ pp2[offset])) @@ -509,7 +509,7 @@ str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p) void masklen2ip (const int masklen, struct in_addr *netmask) { - assert (masklen >= 0 && masklen <= 32); + assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN); netmask->s_addr = maskbytes_network[masklen]; } @@ -612,7 +612,7 @@ str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p) if (ret == 0) return 0; plen = (u_char) atoi (++pnt); - if (plen > 128) + if (plen > IPV6_MAX_BITLEN) return 0; p->prefixlen = plen; } @@ -632,13 +632,13 @@ ip6_masklen (struct in6_addr netmask) pnt = (unsigned char *) & netmask; - while ((*pnt == 0xff) && len < 128) + while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN) { len += 8; pnt++; } - if (len < 128) + if (len < IPV6_MAX_BITLEN) { val = *pnt; while (val) @@ -653,7 +653,7 @@ ip6_masklen (struct in6_addr netmask) void masklen2ip6 (const int masklen, struct in6_addr *netmask) { - assert (masklen >=0 && masklen <= 128); + assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN); memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr)); } -- cgit v1.2.1 From 0f572cde26208254f779933f0e8ec953ad2a3a8a Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 26 Oct 2011 19:34:30 +0400 Subject: bgpd: fix 2 more cases of length error reporting * bgp_attr.c (bgp_attr_originator_id, bgp_attr_cluster_list): use bgp_notify_send_with_data() --- bgpd/bgp_attr.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 829b0176..4967e09a 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1354,9 +1354,10 @@ bgp_attr_originator_id (struct peer *peer, bgp_size_t length, { zlog (peer->log, LOG_ERR, "Bad originator ID length %d", length); - bgp_notify_send (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + startp, total); return -1; } @@ -1388,9 +1389,10 @@ bgp_attr_cluster_list (struct peer *peer, bgp_size_t length, { zlog (peer->log, LOG_ERR, "Bad cluster list length %d", length); - bgp_notify_send (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); + bgp_notify_send_with_data (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + startp, total); return -1; } -- cgit v1.2.1 From 9ebf400a1c21117ff40cb78f0b023bf1cb4e9f6c Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 27 Oct 2011 20:04:08 +0400 Subject: bgpd: fix AS4_PATH attr flag check (BZ#676) AS_PATH is a well-known, transitive path attribute and cannot be flagged as "Partial". This is what commit 77a20b8af32c926176f8492a086d9e4ec670496b implemented, but it did not account, that bgp_attr_aspath() is also used to process AS4_PATH, which is an optional, transitive path attribute and as such may be flagged as "Partial". This change justfies the test condition. --- bgpd/bgp_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 4967e09a..2205e267 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -826,7 +826,7 @@ bgp_attr_aspath (struct peer *peer, bgp_size_t length, total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); /* Check the attribute flags */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) + if (!as4_path && CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL)) { zlog (peer->log, LOG_ERR, "AS_PATH attribute must not be flagged as \"partial\" (%u)", flag); -- cgit v1.2.1 From a994c7b6bb0976e86756f39b89200d711a1d39a3 Mon Sep 17 00:00:00 2001 From: Roderick Schertler Date: Wed, 16 Nov 2011 15:03:14 +0400 Subject: doc: rectify "match ip next-hop" in ripd (BZ#537) --- doc/ripd.texi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/ripd.texi b/doc/ripd.texi index 197bc5af..c6f804af 100644 --- a/doc/ripd.texi +++ b/doc/ripd.texi @@ -424,10 +424,10 @@ must be different. Maybe it'd be better to made new matches - say Match if route destination is permitted by access-list. @end deffn -@deffn {Route Map} {match ip next-hop A.B.C.D} {} -Cisco uses here , @command{ripd} IPv4 address. Match if -route has this next-hop (meaning next-hop listed in the rip route -table - "show ip rip") +@deffn {Route Map} {match ip next-hop @var{word}} {} +@deffnx {Route Map} {match ip next-hop prefix-list @var{word}} {} +Match if route next-hop (meaning next-hop listed in the rip route-table +as displayed by "show ip rip") is permitted by access-list. @end deffn @deffn {Route Map} {match metric <0-4294967295>} {} -- cgit v1.2.1 From 1ce08787910a60635d9b5c09617aaabd55ee00ac Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Wed, 16 Nov 2011 14:22:03 +0400 Subject: ospf6d: implement 'match interface' for route-maps ospf6_routemap_rule_match_interface* was imported from ospfd daemon with minor changes. new CLI options defined. `ospf6_routemap_rule_match_interface' was changed to support IPv6 (ospfv3) route's external information. --- ospf6d/ospf6_asbr.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ospf6d/ospf6_asbr.h | 2 ++ 2 files changed, 91 insertions(+) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index d6c1517e..bc05dc27 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -447,6 +447,7 @@ ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix, memset (&troute, 0, sizeof (troute)); memset (&tinfo, 0, sizeof (tinfo)); troute.route_option = &tinfo; + tinfo.ifindex = ifindex; ret = route_map_apply (ospf6->rmap[type].map, prefix, RMAP_OSPF6, &troute); @@ -780,6 +781,54 @@ ospf6_routemap_rule_match_address_prefixlist_cmd = ospf6_routemap_rule_match_address_prefixlist_free, }; +/* `match interface IFNAME' */ +/* Match function should return 1 if match is success else return + zero. */ +static route_map_result_t +ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct interface *ifp; + struct ospf6_external_info *ei; + + if (type == RMAP_OSPF6) + { + ei = ((struct ospf6_route *) object)->route_option; + ifp = if_lookup_by_name ((char *)rule); + + if (ifp != NULL + && ei->ifindex == ifp->ifindex) + return RMAP_MATCH; + } + + return RMAP_NOMATCH; +} + +/* Route map `interface' match statement. `arg' should be + interface name. */ +static void * +ospf6_routemap_rule_match_interface_compile (const char *arg) +{ + return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +} + +/* Free route map's compiled `interface' value. */ +static void +ospf6_routemap_rule_match_interface_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for interface matching. */ +struct route_map_rule_cmd +ospf6_routemap_rule_match_interface_cmd = +{ + "interface", + ospf6_routemap_rule_match_interface, + ospf6_routemap_rule_match_interface_compile, + ospf6_routemap_rule_match_interface_free +}; + static route_map_result_t ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix, route_map_object_t type, void *object) @@ -957,6 +1006,39 @@ DEFUN (ospf6_routemap_no_match_address_prefixlist, return route_map_command_status (vty, ret); } +/* "match interface" */ +DEFUN (ospf6_routemap_match_interface, + ospf6_routemap_match_interface_cmd, + "match interface WORD", + MATCH_STR + "Match first hop interface of route\n" + "Interface name\n") +{ + return route_map_add_match ((struct route_map_index *) vty->index, + "interface", argv[0]); +} + +/* "no match interface WORD" */ +DEFUN (ospf6_routemap_no_match_interface, + ospf6_routemap_no_match_interface_cmd, + "no match interface", + MATCH_STR + NO_STR + "Match first hop interface of route\n") +{ + int ret = route_map_delete_match ((struct route_map_index *) vty->index, + "interface", (argc == 0) ? NULL : argv[0]); + return route_map_command_status (vty, ret); +} + +ALIAS (ospf6_routemap_no_match_interface, + ospf6_routemap_no_match_interface_val_cmd, + "no match interface WORD", + MATCH_STR + NO_STR + "Match first hop interface of route\n" + "Interface name\n") + /* add "set metric-type" */ DEFUN (ospf6_routemap_set_metric_type, ospf6_routemap_set_metric_type_cmd, @@ -1049,6 +1131,8 @@ ospf6_routemap_init (void) route_map_delete_hook (ospf6_asbr_routemap_update); route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd); + route_map_install_match (&ospf6_routemap_rule_match_interface_cmd); + route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd); route_map_install_set (&ospf6_routemap_rule_set_metric_cmd); route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd); @@ -1057,6 +1141,11 @@ ospf6_routemap_init (void) install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd); install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd); + /* Match interface */ + install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd); + install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd); + install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd); + /* ASE Metric Type (e.g. Type-1/Type-2) */ install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd); install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd); diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index db4561de..5f072cff 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -48,6 +48,8 @@ struct ospf6_external_info struct in6_addr forwarding; /* u_int32_t tag; */ + + unsigned int ifindex; }; /* AS-External-LSA */ -- cgit v1.2.1 From 5009160c748b19a543a2f4fbd01d9de69ca71955 Mon Sep 17 00:00:00 2001 From: Ulrich Weber Date: Wed, 16 Nov 2011 19:32:12 +0400 Subject: bgp: use VTY_GET_INTEGER_RANGE() in bgp_clear() Second patch replaces "VTY_GET_LONG ("AS", as_ul, arg);" by "VTY_GET_INTEGER_RANGE ("AS", as, arg, 1, BGP_AS4_MAX);" as done in all other code, which parses AS numbers. --- bgpd/bgp_vty.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 101f6765..9cb30182 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -4177,18 +4177,10 @@ bgp_clear (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, if (sort == clear_as) { as_t as; - unsigned long as_ul; int find = 0; - VTY_GET_LONG ("AS", as_ul, arg); + VTY_GET_INTEGER_RANGE ("AS", as, arg, 1, BGP_AS4_MAX); - if (!as_ul) - { - vty_out (vty, "Invalid AS number%s", VTY_NEWLINE); - return CMD_WARNING; - } - as = (as_t) as_ul; - for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) { if (peer->as != as) -- cgit v1.2.1 From c0cad4368858d24caedd7e7d2bb776b6d4dd6eb3 Mon Sep 17 00:00:00 2001 From: Ulrich Weber Date: Thu, 17 Nov 2011 21:35:08 +0400 Subject: ripngd: limit max of "timers basic" to 65535 as documented and use VTY_GET_INTEGER_RANGE instead of calling strtoul --- ripngd/ripngd.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index d416255c..8e97c2f8 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2485,28 +2485,10 @@ DEFUN (ripng_timers, unsigned long update; unsigned long timeout; unsigned long garbage; - char *endptr = NULL; - update = strtoul (argv[0], &endptr, 10); - if (update == ULONG_MAX || *endptr != '\0') - { - vty_out (vty, "update timer value error%s", VTY_NEWLINE); - return CMD_WARNING; - } - - timeout = strtoul (argv[1], &endptr, 10); - if (timeout == ULONG_MAX || *endptr != '\0') - { - vty_out (vty, "timeout timer value error%s", VTY_NEWLINE); - return CMD_WARNING; - } - - garbage = strtoul (argv[2], &endptr, 10); - if (garbage == ULONG_MAX || *endptr != '\0') - { - vty_out (vty, "garbage timer value error%s", VTY_NEWLINE); - return CMD_WARNING; - } + VTY_GET_INTEGER_RANGE("update timer", update, argv[0], 0, 65535); + VTY_GET_INTEGER_RANGE("timeout timer", timeout, argv[1], 0, 65535); + VTY_GET_INTEGER_RANGE("garbage timer", garbage, argv[2], 0, 65535); /* Set each timer value. */ ripng->update_time = update; -- cgit v1.2.1 From fd31c50bc30d002e334c9764293f1c4f04a99515 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Mon, 21 Nov 2011 20:26:39 +0400 Subject: ospf6d: justify multicast group management * ospf6_network.[ch] * ospf6_sso(): new function supersedes ospf6_join_allspfrouters(), ospf6_leave_allspfrouters(), ospf6_join_alldrouters() and ospf6_leave_alldrouters() * ospf6_interface.c * ospf6_interface_state_change(): update respectively * interface_up(): ditto * interface_down(): ditto --- ospf6d/ospf6_interface.c | 8 ++--- ospf6d/ospf6_network.c | 82 ++++++------------------------------------------ ospf6d/ospf6_network.h | 6 +--- 3 files changed, 14 insertions(+), 82 deletions(-) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 13d69808..f6420513 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -399,12 +399,12 @@ ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi) prev_state == OSPF6_INTERFACE_BDR) && (next_state != OSPF6_INTERFACE_DR && next_state != OSPF6_INTERFACE_BDR)) - ospf6_leave_alldrouters (oi->interface->ifindex); + ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP); if ((prev_state != OSPF6_INTERFACE_DR && prev_state != OSPF6_INTERFACE_BDR) && (next_state == OSPF6_INTERFACE_DR || next_state == OSPF6_INTERFACE_BDR)) - ospf6_join_alldrouters (oi->interface->ifindex); + ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP); OSPF6_ROUTER_LSA_SCHEDULE (oi->area); if (next_state == OSPF6_INTERFACE_DOWN) @@ -612,7 +612,7 @@ interface_up (struct thread *thread) } /* Join AllSPFRouters */ - ospf6_join_allspfrouters (oi->interface->ifindex); + ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP); /* Update interface route */ ospf6_interface_connected_route_update (oi->interface); @@ -707,7 +707,7 @@ interface_down (struct thread *thread) /* Leave AllSPFRouters */ if (oi->state > OSPF6_INTERFACE_DOWN) - ospf6_leave_allspfrouters (oi->interface->ifindex); + ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_LEAVE_GROUP); ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi); diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 3372238b..e5a1436c 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -120,86 +120,22 @@ ospf6_serv_sock (void) return 0; } +/* ospf6 set socket option */ void -ospf6_join_allspfrouters (u_int ifindex) -{ - struct ipv6_mreq mreq6; - int retval; - - assert (ifindex); - mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6, - sizeof (struct in6_addr)); - - retval = setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, - &mreq6, sizeof (mreq6)); - - if (retval < 0) - zlog_err ("Network: Join AllSPFRouters on ifindex %d failed: %s", - ifindex, safe_strerror (errno)); -#if 0 - else - zlog_debug ("Network: Join AllSPFRouters on ifindex %d", ifindex); -#endif -} - -void -ospf6_leave_allspfrouters (u_int ifindex) -{ - struct ipv6_mreq mreq6; - - assert (ifindex); - mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6, - sizeof (struct in6_addr)); - - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, - &mreq6, sizeof (mreq6)) < 0) - zlog_warn ("Network: Leave AllSPFRouters on ifindex %d Failed: %s", - ifindex, safe_strerror (errno)); -#if 0 - else - zlog_debug ("Network: Leave AllSPFRouters on ifindex %d", ifindex); -#endif -} - -void -ospf6_join_alldrouters (u_int ifindex) -{ - struct ipv6_mreq mreq6; - - assert (ifindex); - mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6, - sizeof (struct in6_addr)); - - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, - &mreq6, sizeof (mreq6)) < 0) - zlog_warn ("Network: Join AllDRouters on ifindex %d Failed: %s", - ifindex, safe_strerror (errno)); -#if 0 - else - zlog_debug ("Network: Join AllDRouters on ifindex %d", ifindex); -#endif -} - -void -ospf6_leave_alldrouters (u_int ifindex) +ospf6_sso (u_int ifindex, struct in6_addr *group, int option) { struct ipv6_mreq mreq6; + int ret; assert (ifindex); mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6, - sizeof (struct in6_addr)); + memcpy (&mreq6.ipv6mr_multiaddr, group, sizeof (struct in6_addr)); - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, - &mreq6, sizeof (mreq6)) < 0) - zlog_warn ("Network: Leave AllDRouters on ifindex %d Failed", ifindex); -#if 0 - else - zlog_debug ("Network: Leave AllDRouters on ifindex %d", ifindex); -#endif + ret = setsockopt (ospf6_sock, IPPROTO_IPV6, option, + &mreq6, sizeof (mreq6)); + if (ret < 0) + zlog_err ("Network: setsockopt (%d) on ifindex %d failed: %s", + option, ifindex, safe_strerror (errno)); } static int diff --git a/ospf6d/ospf6_network.h b/ospf6d/ospf6_network.h index fd8758e8..0526b3e1 100644 --- a/ospf6d/ospf6_network.h +++ b/ospf6d/ospf6_network.h @@ -35,11 +35,7 @@ extern void ospf6_set_pktinfo (void); extern void ospf6_set_checksum (void); extern int ospf6_serv_sock (void); - -extern void ospf6_join_allspfrouters (u_int); -extern void ospf6_leave_allspfrouters (u_int); -extern void ospf6_join_alldrouters (u_int); -extern void ospf6_leave_alldrouters (u_int); +extern void ospf6_sso (u_int ifindex, struct in6_addr *group, int option); extern int ospf6_sendmsg (struct in6_addr *, struct in6_addr *, unsigned int *, struct iovec *); -- cgit v1.2.1 From 1c8afb7c20600165f882d87d7564c6c982c65665 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Tue, 22 Nov 2011 20:15:10 +0400 Subject: bgpd: implement 'match probability' in route-maps New clause 'match probability ' was added in route-maps (bgpd/bgp_routemap.c modified). --- bgpd/bgp_routemap.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 81ff48db..173bf93b 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -790,6 +790,75 @@ struct route_map_rule_cmd route_match_origin_cmd = route_match_origin_compile, route_match_origin_free }; + +/* match probability { */ + +static route_map_result_t +route_match_probability (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + long r; +#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 + r = random(); +#else + r = (long) rand(); +#endif + + switch (*(unsigned *) rule) + { + case 0: break; + case RAND_MAX: return RMAP_MATCH; + default: + if (r < *(unsigned *) rule) + { + return RMAP_MATCH; + } + } + + return RMAP_NOMATCH; +} + +static void * +route_match_probability_compile (const char *arg) +{ + unsigned *lobule; + unsigned perc; + +#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 + srandom (time (NULL)); +#else + srand (time (NULL)); +#endif + + perc = atoi (arg); + lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned)); + + switch (perc) + { + case 0: *lobule = 0; break; + case 100: *lobule = RAND_MAX; break; + default: *lobule = RAND_MAX / 100 * perc; + } + + return lobule; +} + +static void +route_match_probability_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +struct route_map_rule_cmd route_match_probability_cmd = +{ + "probability", + route_match_probability, + route_match_probability_compile, + route_match_probability_free +}; + +/* } */ + /* `set ip next-hop IP_ADDRESS' */ /* Set nexthop to object. ojbect must be pointer to struct attr. */ @@ -2444,6 +2513,38 @@ ALIAS (no_match_ip_next_hop, "IP access-list number (expanded range)\n" "IP Access-list name\n") +/* match probability { */ + +DEFUN (match_probability, + match_probability_cmd, + "match probability <0-100>", + MATCH_STR + "Match portion of routes defined by percentage value\n" + "Percentage of routes\n") +{ + return bgp_route_match_add (vty, vty->index, "probability", argv[0]); +} + +DEFUN (no_match_probability, + no_match_probability_cmd, + "no match probability", + NO_STR + MATCH_STR + "Match portion of routes defined by percentage value\n") +{ + return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL); +} + +ALIAS (no_match_probability, + no_match_probability_val_cmd, + "no match probability <1-99>", + NO_STR + MATCH_STR + "Match portion of routes defined by percentage value\n" + "Percentage of routes\n") + +/* } */ + DEFUN (match_ip_route_source, match_ip_route_source_cmd, "match ip route-source (<1-199>|<1300-2699>|WORD)", @@ -3731,6 +3832,7 @@ bgp_route_map_init (void) route_map_install_match (&route_match_ecommunity_cmd); route_map_install_match (&route_match_metric_cmd); route_map_install_match (&route_match_origin_cmd); + route_map_install_match (&route_match_probability_cmd); route_map_install_set (&route_set_ip_nexthop_cmd); route_map_install_set (&route_set_local_pref_cmd); @@ -3762,7 +3864,6 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &match_ip_route_source_cmd); install_element (RMAP_NODE, &no_match_ip_route_source_cmd); install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd); - install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd); install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd); install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd); @@ -3790,6 +3891,9 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &match_origin_cmd); install_element (RMAP_NODE, &no_match_origin_cmd); install_element (RMAP_NODE, &no_match_origin_val_cmd); + install_element (RMAP_NODE, &match_probability_cmd); + install_element (RMAP_NODE, &no_match_probability_cmd); + install_element (RMAP_NODE, &no_match_probability_val_cmd); install_element (RMAP_NODE, &set_ip_nexthop_cmd); install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd); -- cgit v1.2.1 From 844ee4a8acf1a7b34e6a4a0bdf701496302a7416 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Fri, 25 Nov 2011 17:56:21 +0400 Subject: isisd: indent longopts array --- isisd/isis_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/isisd/isis_main.c b/isisd/isis_main.c index c5e824c1..45e94081 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -72,16 +72,16 @@ struct zebra_privs_t isisd_privs = { /* isisd options */ struct option longopts[] = { - {"daemon", no_argument, NULL, 'd'}, + {"daemon", no_argument, NULL, 'd'}, {"config_file", required_argument, NULL, 'f'}, - {"pid_file", required_argument, NULL, 'i'}, - {"vty_addr", required_argument, NULL, 'A'}, - {"vty_port", required_argument, NULL, 'P'}, - {"user", required_argument, NULL, 'u'}, - {"group", required_argument, NULL, 'g'}, - {"version", no_argument, NULL, 'v'}, - {"dryrun", no_argument, NULL, 'C'}, - {"help", no_argument, NULL, 'h'}, + {"pid_file", required_argument, NULL, 'i'}, + {"vty_addr", required_argument, NULL, 'A'}, + {"vty_port", required_argument, NULL, 'P'}, + {"user", required_argument, NULL, 'u'}, + {"group", required_argument, NULL, 'g'}, + {"version", no_argument, NULL, 'v'}, + {"dryrun", no_argument, NULL, 'C'}, + {"help", no_argument, NULL, 'h'}, {0} }; -- cgit v1.2.1 From 271ee735ed3a42a1fe52f6401ddf72bd5d3e4f10 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Fri, 25 Nov 2011 18:51:48 +0400 Subject: quagga: option "-z" ("--socket ") added All daemons modified to support custom path to zserv socket. lib: generalize a zclient connection zclient_socket_connect added. zclient_socket and zclient_socket_un were hidden under static expression. "zclient_serv_path_set" modified. --- bgpd/bgp_main.c | 7 +++++- bgpd/bgp_nexthop.c | 7 +----- isisd/isis_main.c | 8 ++++++- lib/zclient.c | 62 +++++++++++++++++++++++++++++++++++++++++++++-------- lib/zclient.h | 7 ++---- ospf6d/ospf6_main.c | 7 +++++- ospfd/ospf_main.c | 46 ++++++++++++++++++++++----------------- ripd/rip_main.c | 8 ++++++- ripngd/ripng_main.c | 9 ++++++-- zebra/main.c | 12 ++++++++--- zebra/zserv.c | 4 ++-- zebra/zserv.h | 2 +- 12 files changed, 127 insertions(+), 52 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 4a38c15a..778067a8 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -54,6 +54,7 @@ static const struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "bgp_port", required_argument, NULL, 'p'}, { "listenon", required_argument, NULL, 'l'}, { "vty_addr", required_argument, NULL, 'A'}, @@ -150,6 +151,7 @@ redistribution between different routing protocols.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -p, --bgp_port Set bgp protocol's port number\n\ -l, --listenon Listen on specified address (implies -n)\n\ -A, --vty_addr Set vty's bind address\n\ @@ -328,7 +330,7 @@ main (int argc, char **argv) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0); if (opt == EOF) break; @@ -346,6 +348,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'p': tmp_port = atoi (optarg); if (tmp_port <= 0 || tmp_port > 0xffff) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 1a2923cc..f8d1adec 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -1064,12 +1064,7 @@ zlookup_connect (struct thread *t) if (zlookup->sock != -1) return 0; -#ifdef HAVE_TCP_ZEBRA - zlookup->sock = zclient_socket (); -#else - zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH); -#endif /* HAVE_TCP_ZEBRA */ - if (zlookup->sock < 0) + if (zclient_socket_connect (zlookup) < 0) return -1; return 0; diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 45e94081..15d85d6d 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -34,6 +34,7 @@ #include "privs.h" #include "sigevent.h" #include "filter.h" +#include "zclient.h" #include "isisd/dict.h" #include "include-netbsd/iso.h" @@ -75,6 +76,7 @@ struct option longopts[] = { {"daemon", no_argument, NULL, 'd'}, {"config_file", required_argument, NULL, 'f'}, {"pid_file", required_argument, NULL, 'i'}, + {"socket", required_argument, NULL, 'z'}, {"vty_addr", required_argument, NULL, 'A'}, {"vty_port", required_argument, NULL, 'P'}, {"user", required_argument, NULL, 'u'}, @@ -130,6 +132,7 @@ Daemon which manages IS-IS routing\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ @@ -246,7 +249,7 @@ main (int argc, char **argv, char **envp) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:vC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hA:p:P:u:g:vC", longopts, 0); if (opt == EOF) break; @@ -264,6 +267,9 @@ main (int argc, char **argv, char **envp) case 'i': pid_file = optarg; break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'A': vty_addr = optarg; break; diff --git a/lib/zclient.c b/lib/zclient.c index 52a3627d..3d5be918 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -41,6 +41,8 @@ static void zclient_event (enum event, struct zclient *); extern struct thread_master *master; +char *zclient_serv_path = NULL; + /* This file local debug flag. */ int zclient_debug = 0; @@ -143,8 +145,10 @@ zclient_reset (struct zclient *zclient) zclient_init (zclient, zclient->redist_default); } +#ifdef HAVE_TCP_ZEBRA + /* Make socket to zebra daemon. Return zebra socket. */ -int +static int zclient_socket(void) { int sock; @@ -175,10 +179,12 @@ zclient_socket(void) return sock; } +#endif /* HAVE_TCP_ZEBRA */ + /* For sockaddr_un. */ #include -int +static int zclient_socket_un (const char *path) { int ret; @@ -208,6 +214,24 @@ zclient_socket_un (const char *path) return sock; } +/** + * Connect to zebra daemon. + * @param zclient a pointer to zclient structure + * @return socket fd just to make sure that connection established + * @see zclient_init + * @see zclient_new + */ +int +zclient_socket_connect (struct zclient *zclient) +{ +#ifdef HAVE_TCP_ZEBRA + zclient->sock = zclient_socket (); +#else + zclient->sock = zclient_socket_un (zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH); +#endif + return zclient->sock; +} + static int zclient_failed(struct zclient *zclient) { @@ -313,13 +337,7 @@ zclient_start (struct zclient *zclient) if (zclient->t_connect) return 0; - /* Make socket. */ -#ifdef HAVE_TCP_ZEBRA - zclient->sock = zclient_socket (); -#else - zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH); -#endif /* HAVE_TCP_ZEBRA */ - if (zclient->sock < 0) + if (zclient_socket_connect(zclient) < 0) { if (zclient_debug) zlog_debug ("zclient connection fail"); @@ -1018,3 +1036,29 @@ zclient_event (enum event event, struct zclient *zclient) break; } } + +void +zclient_serv_path_set (char *path) +{ + struct stat sb; + + /* reset */ + zclient_serv_path = NULL; + + /* test if `path' is socket. don't set it otherwise. */ + if (stat(path, &sb) == -1) + { + zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path); + return; + } + + if ((sb.st_mode & S_IFMT) != S_IFSOCK) + { + zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path); + return; + } + + /* it seems that path is unix socket */ + zclient_serv_path = path; +} + diff --git a/lib/zclient.h b/lib/zclient.h index 21786ab8..5c3db382 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -127,11 +127,8 @@ extern void zclient_stop (struct zclient *); extern void zclient_reset (struct zclient *); extern void zclient_free (struct zclient *); -/* Get TCP socket connection to zebra daemon at loopback address. */ -extern int zclient_socket (void); - -/* Get unix stream socket connection to zebra daemon at given path. */ -extern int zclient_socket_un (const char *); +extern int zclient_socket_connect (struct zclient *); +extern void zclient_serv_path_set (char *path); /* Send redistribute command to zebra daemon. Do not update zclient state. */ extern int zebra_redistribute_send (int command, struct zclient *, int type); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index ced2ef2a..235a6858 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -77,6 +77,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, { "user", required_argument, NULL, 'u'}, @@ -115,6 +116,7 @@ Daemon which manages OSPF version 3.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ @@ -202,7 +204,7 @@ main (int argc, char *argv[], char *envp[]) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hp:A:P:u:g:vC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hp:A:P:u:g:vC", longopts, 0); if (opt == EOF) break; @@ -223,6 +225,9 @@ main (int argc, char *argv[], char *envp[]) case 'i': pid_file = optarg; break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'P': /* Deal with atoi() returning 0 on failure, and ospf6d not listening on ospf6d port... */ diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 8b9a3458..bad674b6 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -38,6 +38,7 @@ #include "memory.h" #include "privs.h" #include "sigevent.h" +#include "zclient.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -80,6 +81,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, @@ -116,6 +118,7 @@ Daemon which manages OSPF.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ @@ -191,30 +194,11 @@ main (int argc, char **argv) /* get program name */ progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); - /* Invoked by a priviledged user? -- endo. */ - if (geteuid () != 0) - { - errno = EPERM; - perror (progname); - exit (1); - } - - zlog_default = openzlog (progname, ZLOG_OSPF, - LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); - - /* OSPF master init. */ - ospf_master_init (); - -#ifdef SUPPORT_OSPF_API - /* OSPF apiserver is disabled by default. */ - ospf_apiserver_enable = 0; -#endif /* SUPPORT_OSPF_API */ - while (1) { int opt; - opt = getopt_long (argc, argv, "df:i:hA:P:u:g:avC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:avC", longopts, 0); if (opt == EOF) break; @@ -235,6 +219,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'P': /* Deal with atoi() returning 0 on failure, and ospfd not listening on ospfd port... */ @@ -274,6 +261,25 @@ main (int argc, char **argv) } } + /* Invoked by a priviledged user? -- endo. */ + if (geteuid () != 0) + { + errno = EPERM; + perror (progname); + exit (1); + } + + zlog_default = openzlog (progname, ZLOG_OSPF, + LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); + + /* OSPF master init. */ + ospf_master_init (); + +#ifdef SUPPORT_OSPF_API + /* OSPF apiserver is disabled by default. */ + ospf_apiserver_enable = 0; +#endif /* SUPPORT_OSPF_API */ + /* Initializations. */ master = om->master; diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 57b5f3af..ccb5fa01 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -32,6 +32,7 @@ #include "log.h" #include "privs.h" #include "sigevent.h" +#include "zclient.h" #include "ripd/ripd.h" @@ -41,6 +42,7 @@ static struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "help", no_argument, NULL, 'h'}, { "dryrun", no_argument, NULL, 'C'}, { "vty_addr", required_argument, NULL, 'A'}, @@ -109,6 +111,7 @@ Daemon which manages RIP version 1 and 2.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -C, --dryrun Check configuration for validity and exit\n\ @@ -206,7 +209,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "df:i:hA:P:u:g:rvC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:rvC", longopts, 0); if (opt == EOF) break; @@ -227,6 +230,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'P': /* Deal with atoi() returning 0 on failure, and ripd not listening on rip port... */ diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index 85209a15..f4a62440 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -47,6 +47,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, @@ -112,6 +113,7 @@ Daemon which manages RIPng.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -r, --retain When program terminates, retain added route by ripngd.\n\ @@ -205,7 +207,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "df:i:hA:P:u:g:vC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:vC", longopts, 0); if (opt == EOF) break; @@ -225,7 +227,10 @@ main (int argc, char **argv) break; case 'i': pid_file = optarg; - break; + break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'P': /* Deal with atoi() returning 0 on failure, and ripngd not listening on ripngd port... */ diff --git a/zebra/main.c b/zebra/main.c index d829c046..5f26ce24 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -71,6 +71,7 @@ struct option longopts[] = { "keep_kernel", no_argument, NULL, 'k'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, @@ -128,6 +129,7 @@ usage (char *progname, int status) "-d, --daemon Runs in daemon mode\n"\ "-f, --config_file Set configuration file name\n"\ "-i, --pid_file Set process identifier file name\n"\ + "-z, --socket Set path of zebra socket\n"\ "-k, --keep_kernel Don't delete old routes which installed by "\ "zebra.\n"\ "-C, --dryrun Check configuration for validity and exit\n"\ @@ -214,6 +216,7 @@ main (int argc, char **argv) char *config_file = NULL; char *progname; struct thread thread; + char *zserv_path = NULL; /* Set umask before anything for security */ umask (0027); @@ -229,9 +232,9 @@ main (int argc, char **argv) int opt; #ifdef HAVE_NETLINK - opt = getopt_long (argc, argv, "bdkf:i:hA:P:ru:g:vs:C", longopts, 0); + opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vs:C", longopts, 0); #else - opt = getopt_long (argc, argv, "bdkf:i:hA:P:ru:g:vC", longopts, 0); + opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vC", longopts, 0); #endif /* HAVE_NETLINK */ if (opt == EOF) @@ -261,6 +264,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'z': + zserv_path = optarg; + break; case 'P': /* Deal with atoi() returning 0 on failure, and zebra not listening on zebra port... */ @@ -386,7 +392,7 @@ main (int argc, char **argv) pid = getpid (); /* This must be done only after locking pidfile (bug #403). */ - zebra_zserv_socket_init (); + zebra_zserv_socket_init (zserv_path); /* Make vty server socket. */ vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH); diff --git a/zebra/zserv.c b/zebra/zserv.c index dc3d432b..d558b2d2 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1733,11 +1733,11 @@ zebra_init (void) /* Make zebra server socket, wiping any existing one (see bug #403). */ void -zebra_zserv_socket_init (void) +zebra_zserv_socket_init (char *path) { #ifdef HAVE_TCP_ZEBRA zebra_serv (); #else - zebra_serv_un (ZEBRA_SERV_PATH); + zebra_serv_un (path ? path : ZEBRA_SERV_PATH); #endif /* HAVE_TCP_ZEBRA */ } diff --git a/zebra/zserv.h b/zebra/zserv.h index a7371830..5e8bccac 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -89,7 +89,7 @@ struct zebra_t /* Prototypes. */ extern void zebra_init (void); extern void zebra_if_init (void); -extern void zebra_zserv_socket_init (void); +extern void zebra_zserv_socket_init (char *path); extern void hostinfo_get (void); extern void rib_init (void); extern void interface_list (void); -- cgit v1.2.1 From d5cd9a9758932dc644eb8b3f0eff3d2e17a7d677 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Wed, 30 Nov 2011 21:03:44 +0400 Subject: lib: clearing zclient.c for some cases of building lib/zclient.c: using of HAVE_TCP_ZEBRA in zclient_socket_* definitions extended by else clause. --- lib/zclient.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/zclient.c b/lib/zclient.c index 3d5be918..a5d5b7ff 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -179,7 +179,7 @@ zclient_socket(void) return sock; } -#endif /* HAVE_TCP_ZEBRA */ +#else /* For sockaddr_un. */ #include @@ -214,6 +214,8 @@ zclient_socket_un (const char *path) return sock; } +#endif /* HAVE_TCP_ZEBRA */ + /** * Connect to zebra daemon. * @param zclient a pointer to zclient structure -- cgit v1.2.1 From 42140fb1b1f88310565c6b1d36645aa15c58424d Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 2 Dec 2011 20:02:40 +0400 Subject: ospfd: spelling --- ospfd/ospf_lsa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 132a281c..2f50676e 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -1679,7 +1679,7 @@ ospf_external_lsa_new (struct ospf *ospf, if (ei == NULL) { if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type5]: External info is NULL, could not originated"); + zlog_debug ("LSA[Type5]: External info is NULL, can't originate"); return NULL; } @@ -2915,7 +2915,7 @@ ospf_maxage_lsa_remover (struct thread *thread) /* Remove LSA from the LSDB */ if (IS_LSA_SELF (lsa)) if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ", + zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ", lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa); if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) -- cgit v1.2.1 From 1b960ed436a5515747ff4f4d15b1389e43f3b63c Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 3 Dec 2011 17:45:17 +0400 Subject: build: delete .cvsignore files --- .cvsignore | 30 ------------------------------ bgpd/.cvsignore | 15 --------------- doc/.cvsignore | 31 ------------------------------- doc/mpls/.cvsignore | 2 -- guile/.cvsignore | 7 ------- init/.cvsignore | 3 --- isisd/.cvsignore | 12 ------------ isisd/include-netbsd/.cvsignore | 3 --- isisd/topology/.cvsignore | 9 --------- lib/.cvsignore | 14 -------------- m4/.cvsignore | 4 ---- ospf6d/.cvsignore | 15 --------------- ospfclient/.cvsignore | 13 ------------- ospfd/.cvsignore | 14 -------------- pkgsrc/.cvsignore | 5 ----- ports/.cvsignore | 3 --- ports/files/.cvsignore | 3 --- ports/pkg/.cvsignore | 3 --- redhat/.cvsignore | 7 ------- ripd/.cvsignore | 14 -------------- ripngd/.cvsignore | 14 -------------- solaris/.cvsignore | 14 -------------- tests/.cvsignore | 22 ---------------------- tools/.cvsignore | 3 --- vtysh/.cvsignore | 13 ------------- watchquagga/.cvsignore | 13 ------------- zebra/.cvsignore | 13 ------------- 27 files changed, 299 deletions(-) delete mode 100644 .cvsignore delete mode 100644 bgpd/.cvsignore delete mode 100644 doc/.cvsignore delete mode 100644 doc/mpls/.cvsignore delete mode 100644 guile/.cvsignore delete mode 100644 init/.cvsignore delete mode 100644 isisd/.cvsignore delete mode 100644 isisd/include-netbsd/.cvsignore delete mode 100644 isisd/topology/.cvsignore delete mode 100644 lib/.cvsignore delete mode 100644 m4/.cvsignore delete mode 100644 ospf6d/.cvsignore delete mode 100644 ospfclient/.cvsignore delete mode 100644 ospfd/.cvsignore delete mode 100644 pkgsrc/.cvsignore delete mode 100644 ports/.cvsignore delete mode 100644 ports/files/.cvsignore delete mode 100644 ports/pkg/.cvsignore delete mode 100644 redhat/.cvsignore delete mode 100644 ripd/.cvsignore delete mode 100644 ripngd/.cvsignore delete mode 100644 solaris/.cvsignore delete mode 100644 tests/.cvsignore delete mode 100644 tools/.cvsignore delete mode 100644 vtysh/.cvsignore delete mode 100644 watchquagga/.cvsignore delete mode 100644 zebra/.cvsignore diff --git a/.cvsignore b/.cvsignore deleted file mode 100644 index a67bba01..00000000 --- a/.cvsignore +++ /dev/null @@ -1,30 +0,0 @@ -config.log -config.h -config.cache -config.status -config.guess -config.sub -ltmain.sh -stamp-h -stamp-h[0-9]* -*-stamp -Makefile -INSTALL -.deps -depcomp -missing -install-sh -autom4te*.cache -configure.lineno -configure -config.h.in -aclocal.m4 -Makefile.in -zebra-[0-9.][0-9.][0-9.]*.tar.gz -quagga-[0-9.][0-9.][0-9.]*.tar.gz -quagga-[0-9.][0-9.][0-9.]*.tar.gz.asc -.nfs* -libtool -.arch-inventory -.arch-ids -{arch} diff --git a/bgpd/.cvsignore b/bgpd/.cvsignore deleted file mode 100644 index f4504f62..00000000 --- a/bgpd/.cvsignore +++ /dev/null @@ -1,15 +0,0 @@ -Makefile -Makefile.in -*.o -bgpd -bgp_btoa -bgpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/doc/.cvsignore b/doc/.cvsignore deleted file mode 100644 index 43987b24..00000000 --- a/doc/.cvsignore +++ /dev/null @@ -1,31 +0,0 @@ -Makefile -Makefile.in -mdate-sh -draft-zebra-00.txt -zebra.info-* -zebra.html -defines.texi -version.texi -quagga.html -quagga.info -*.pdf -*.eps -quagga.ps -quagga.dvi -stamp-vti -.nfs* -*.aux -*.cp -*.cps -*.fn -*.fns -*.ky -*.kys -*.log -*.op -*.pg -*.toc -*.tp -*.vr -.arch-inventory -.arch-ids diff --git a/doc/mpls/.cvsignore b/doc/mpls/.cvsignore deleted file mode 100644 index 1218df92..00000000 --- a/doc/mpls/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.arch-ids -.arch-inventory diff --git a/guile/.cvsignore b/guile/.cvsignore deleted file mode 100644 index d345fc35..00000000 --- a/guile/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -Makefile -*.o -zebra-guile -Makefile.in -.nfs* -.arch-inventory -.arch-ids diff --git a/init/.cvsignore b/init/.cvsignore deleted file mode 100644 index 3c447f5b..00000000 --- a/init/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile -Makefile.in -.nfs* diff --git a/isisd/.cvsignore b/isisd/.cvsignore deleted file mode 100644 index 26aa85cb..00000000 --- a/isisd/.cvsignore +++ /dev/null @@ -1,12 +0,0 @@ -Makefile -Makefile.in -*.o -isisd -.deps -isisd.conf -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/isisd/include-netbsd/.cvsignore b/isisd/include-netbsd/.cvsignore deleted file mode 100644 index 73bcf19d..00000000 --- a/isisd/include-netbsd/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.arch-inventory -.arch-ids - diff --git a/isisd/topology/.cvsignore b/isisd/topology/.cvsignore deleted file mode 100644 index b0ae823b..00000000 --- a/isisd/topology/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -.arch-inventory -.arch-ids diff --git a/lib/.cvsignore b/lib/.cvsignore deleted file mode 100644 index 806696d7..00000000 --- a/lib/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -*.o -*.lo -*.la -version.c -version.h -.deps -.nfs* -.libs -.arch-inventory -.arch-ids -memtypes.h -route_types.h diff --git a/m4/.cvsignore b/m4/.cvsignore deleted file mode 100644 index 2f02fdbd..00000000 --- a/m4/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -Makefile -Makefile.in -.arch-inventory -.arch-ids diff --git a/ospf6d/.cvsignore b/ospf6d/.cvsignore deleted file mode 100644 index 522397a1..00000000 --- a/ospf6d/.cvsignore +++ /dev/null @@ -1,15 +0,0 @@ -Makefile.in -Makefile -*.o -*.patch -ospf6d -ospf6d.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/ospfclient/.cvsignore b/ospfclient/.cvsignore deleted file mode 100644 index d6de29ab..00000000 --- a/ospfclient/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -Makefile -Makefile.in -*.o -ospfclient -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/ospfd/.cvsignore b/ospfd/.cvsignore deleted file mode 100644 index 6fce629e..00000000 --- a/ospfd/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -*.o -ospfd -ospfd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/pkgsrc/.cvsignore b/pkgsrc/.cvsignore deleted file mode 100644 index 818bd175..00000000 --- a/pkgsrc/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -Makefile -Makefile.in -*.sh -.arch-inventory -.arch-ids diff --git a/ports/.cvsignore b/ports/.cvsignore deleted file mode 100644 index 73bcf19d..00000000 --- a/ports/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.arch-inventory -.arch-ids - diff --git a/ports/files/.cvsignore b/ports/files/.cvsignore deleted file mode 100644 index 73bcf19d..00000000 --- a/ports/files/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.arch-inventory -.arch-ids - diff --git a/ports/pkg/.cvsignore b/ports/pkg/.cvsignore deleted file mode 100644 index 73bcf19d..00000000 --- a/ports/pkg/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.arch-inventory -.arch-ids - diff --git a/redhat/.cvsignore b/redhat/.cvsignore deleted file mode 100644 index 98ca65a2..00000000 --- a/redhat/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -zebra.spec -quagga.spec -Makefile -Makefile.in -.nfs* -.arch-inventory -.arch-ids diff --git a/ripd/.cvsignore b/ripd/.cvsignore deleted file mode 100644 index 41fd8c82..00000000 --- a/ripd/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -*.o -ripd -ripd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/ripngd/.cvsignore b/ripngd/.cvsignore deleted file mode 100644 index 48f45cef..00000000 --- a/ripngd/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -*.o -ripngd -ripngd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/solaris/.cvsignore b/solaris/.cvsignore deleted file mode 100644 index 810874ca..00000000 --- a/solaris/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -?.manifest -*.xml -pkginfo.*.full -pkginfo.tmpl -prototype.daemons -prototype.dev -prototype.doc -prototype.libs -prototype.smf -quagga.init -*.pkg -*.pkg.gz diff --git a/tests/.cvsignore b/tests/.cvsignore deleted file mode 100644 index 4c3e50dc..00000000 --- a/tests/.cvsignore +++ /dev/null @@ -1,22 +0,0 @@ -Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -testsig -.arch-inventory -.arch-ids -testbuffer -testmemory -testsig -aspathtest -heavy -heavythread -heavywq -testprivs -teststream diff --git a/tools/.cvsignore b/tools/.cvsignore deleted file mode 100644 index 73bcf19d..00000000 --- a/tools/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.arch-inventory -.arch-ids - diff --git a/vtysh/.cvsignore b/vtysh/.cvsignore deleted file mode 100644 index ed3f1f39..00000000 --- a/vtysh/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -Makefile -Makefile.in -*.o -vtysh -tags -TAGS -.deps -vtysh_cmd.c -.nfs* -extract.pl -.libs -.arch-inventory -.arch-ids diff --git a/watchquagga/.cvsignore b/watchquagga/.cvsignore deleted file mode 100644 index c661510b..00000000 --- a/watchquagga/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -Makefile -Makefile.in -*.o -watchquagga -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/zebra/.cvsignore b/zebra/.cvsignore deleted file mode 100644 index 59c5889e..00000000 --- a/zebra/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -Makefile -Makefile.in -*.o -zebra -zebra.conf -client -tags -TAGS -.deps -.nfs* -.libs -.arch-inventory -.arch-ids -- cgit v1.2.1 From 6258c2ae35ec40c07e87c010423e6b93ac39bd66 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 5 Dec 2011 19:36:06 +0400 Subject: zebra: spelling --- zebra/kernel_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index bd129dc2..e7ceea54 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -618,7 +618,7 @@ ifam_read_mesg (struct ifa_msghdr *ifm, /* Assert read up end point matches to end point */ if (pnt != end) - zlog_warn ("ifam_read() does't read all socket data"); + zlog_warn ("ifam_read() doesn't read all socket data"); } /* Interface's address information get. */ @@ -766,7 +766,7 @@ rtm_read_mesg (struct rt_msghdr *rtm, /* Assert read up to the end of pointer. */ if (pnt != end) - zlog (NULL, LOG_WARNING, "rtm_read() does't read all socket data."); + zlog (NULL, LOG_WARNING, "rtm_read() doesn't read all socket data."); return rtm->rtm_flags; } -- cgit v1.2.1 From 7b0d1c6d31d50fbf74f84cb60daaedd904b35171 Mon Sep 17 00:00:00 2001 From: Jaroslav Fojtik Date: Sun, 11 Dec 2011 18:22:16 +0400 Subject: ospfd: more info in LSA checksum warning (BZ#685) --- ospfd/ospf_packet.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index c347f31d..1c1a1e69 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -1520,8 +1520,13 @@ ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s, sum = lsah->checksum; if (sum != ospf_lsa_checksum (lsah)) { - zlog_warn ("Link State Update: LSA checksum error %x, %x.", - sum, lsah->checksum); + /* (bug #685) more details in a one-line message make it possible + * to identify problem source on the one hand and to have a better + * chance to compress repeated messages in syslog on the other */ + zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s", + sum, lsah->checksum, inet_ntoa (lsah->id), + inet_ntoa (nbr->src), inet_ntoa (nbr->router_id), + inet_ntoa (lsah->adv_router)); continue; } -- cgit v1.2.1 From bf19277c341e6c1b94046c628c0e6d0f0b20d536 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 1 Jan 2012 16:33:12 +0400 Subject: Revert "lib: optimize apply_mask_ipv6()" Experience with IPv4 counterpart of this function suggests, that this way of type-punning is likely to cause errors. --- lib/prefix.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 54b9bc8a..f4b0c4f1 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -660,13 +660,23 @@ masklen2ip6 (const int masklen, struct in6_addr *netmask) void apply_mask_ipv6 (struct prefix_ipv6 *p) { - assert (p->prefixlen >= 0 && p->prefixlen <= IPV6_MAX_BITLEN); - u_int32_t *addr_word = (u_int32_t *) &p->prefix; - u_int32_t *mask_word = (u_int32_t *) (maskbytes6 + p->prefixlen); - *addr_word++ &= *mask_word++; - *addr_word++ &= *mask_word++; - *addr_word++ &= *mask_word++; - *addr_word &= *mask_word; + u_char *pnt; + int index; + int offset; + + index = p->prefixlen / 8; + + if (index < 16) + { + pnt = (u_char *) &p->prefix; + offset = p->prefixlen % 8; + + pnt[index] &= maskbit[offset]; + index++; + + while (index < 16) + pnt[index++] = 0; + } } void -- cgit v1.2.1 From e1fabbb86c2558b336b83de443a4fde4b2a8db90 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 4 Dec 2011 23:21:55 +0400 Subject: lib: optimize ip_masklen() The new implementation makes use of a 64KB mapping table, which makes it possible to compute masklen faster and with constant execution time. The map also allows for additional version of the function, which can detect errors in input argument. The previous implementation had a variable cost of execution, which depended on masklen in a non-linear manner, and at its worst (/31) was 4 times slower, than the new implementation. The only case of old function just slightly outperforming the new one is /0, which is of little practical interest. --- lib/prefix.c | 2101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 2076 insertions(+), 25 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index f4b0c4f1..19a52610 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -235,6 +235,2080 @@ static const struct in6_addr maskbytes6[] = /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } }, /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } } }; +/* +The table below maps any 16-bit wide network byte ordered integer to one +of 17 ([0..16]) possible bitmask lengths, when the bitmask is contiguous, +or to -1, when it is not. + + 0 0x0000 0000 0000 0000 0000 /0 + 128 0x0080 0000 0000 1000 0000 /1 + 192 0x00c0 0000 0000 1100 0000 /2 + 224 0x00e0 0000 0000 1110 0000 /3 + 240 0x00f0 0000 0000 1111 0000 /4 + 248 0x00f8 0000 0000 1111 1000 /5 + 252 0x00fc 0000 0000 1111 1100 /6 + 254 0x00fe 0000 0000 1111 1110 /7 + 255 0x00ff 0000 0000 1111 1111 /8 +33023 0x80ff 1000 0000 1111 1111 /9 +49407 0xc0ff 1100 0000 1111 1111 /10 +57599 0xe0ff 1110 0000 1111 1111 /11 +61695 0xf0ff 1111 0000 1111 1111 /12 +63743 0xf8ff 1111 1000 1111 1111 /13 +64767 0xfcff 1111 1100 1111 1111 /14 +65279 0xfeff 1111 1110 1111 1111 /15 +65535 0xffff 1111 1111 1111 1111 /16 +*/ +static const char map64kto17_nbo[0xffff + 1] = +{ + 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, 6, -1, 7, 8, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, +}; /* Number of bits in prefix type. */ #ifndef PNBBY @@ -518,31 +2592,8 @@ masklen2ip (const int masklen, struct in_addr *netmask) u_char ip_masklen (struct in_addr netmask) { - u_char len; - u_char *pnt; - u_char *end; - u_char val; - - len = 0; - pnt = (u_char *) &netmask; - end = pnt + 4; - - while ((pnt < end) && (*pnt == 0xff)) - { - len+= 8; - pnt++; - } - - if (pnt < end) - { - val = *pnt; - while (val) - { - len++; - val <<= 1; - } - } - return len; + u_int16_t * int16 = (u_int16_t *) &netmask.s_addr; + return map64kto17_nbo[int16[0]] + map64kto17_nbo[int16[1]]; } /* Apply mask to IPv4 prefix (network byte order). */ -- cgit v1.2.1 From ce77002e908e8c9eeff780a6a34143af6758a17f Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 16 Dec 2011 16:25:02 +0400 Subject: lib: fix type-punning in ip_masklen() ip_masklen() was likely to return incorrect results after being compiled with -fstrict-aliasing (-O2, -O3, -Os) --- lib/prefix.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 19a52610..23202b62 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -2592,8 +2592,13 @@ masklen2ip (const int masklen, struct in_addr *netmask) u_char ip_masklen (struct in_addr netmask) { - u_int16_t * int16 = (u_int16_t *) &netmask.s_addr; - return map64kto17_nbo[int16[0]] + map64kto17_nbo[int16[1]]; + union + { + u_int32_t int32; + u_int16_t int16[2]; + } u; + u.int32 = netmask.s_addr; + return map64kto17_nbo[u.int16[0]] + map64kto17_nbo[u.int16[1]]; } /* Apply mask to IPv4 prefix (network byte order). */ -- cgit v1.2.1 From ed269db39a167251f9b7e8e261c7f53902c094f9 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 14:04:12 +0400 Subject: lib: call filter delete hook before freeing access list The delete_hook was being run after calling access list delete function. This would cause ospf to dereference a NULL, in ospf_filter_update because 'access->name' was already freed. See also: https://bugzilla.vyatta.com/show_bug.cgi?id=7654 --- lib/filter.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/filter.c b/lib/filter.c index af8d587f..69341824 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -1337,13 +1337,13 @@ DEFUN (no_access_list_all, master = access->master; - /* Delete all filter from access-list. */ - access_list_delete (access); - /* Run hook function. */ if (master->delete_hook) (*master->delete_hook) (access); + /* Delete all filter from access-list. */ + access_list_delete (access); + return CMD_SUCCESS; } @@ -1508,13 +1508,13 @@ DEFUN (no_ipv6_access_list_all, master = access->master; - /* Delete all filter from access-list. */ - access_list_delete (access); - /* Run hook function. */ if (master->delete_hook) (*master->delete_hook) (access); + /* Delete all filter from access-list. */ + access_list_delete (access); + return CMD_SUCCESS; } -- cgit v1.2.1 From c17fbd6b1eb38e71aba65c593fa41f2e54f0b896 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 14:09:18 +0400 Subject: lib: fix memory leak on connect() failure Change sockunion_log() to not use strdup(). This fixes a small memory leak that occurs on every failed connect(), and is simpler/cleaner. --- lib/sockunion.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/sockunion.c b/lib/sockunion.c index d1f6d80b..10224a05 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -297,27 +297,24 @@ sockunion_sizeof (union sockunion *su) } /* return sockunion structure : this function should be revised. */ -static char * -sockunion_log (union sockunion *su) +static const char * +sockunion_log (union sockunion *su, char *buf, size_t len) { - static char buf[SU_ADDRSTRLEN]; - switch (su->sa.sa_family) { case AF_INET: - snprintf (buf, SU_ADDRSTRLEN, "%s", inet_ntoa (su->sin.sin_addr)); - break; + return inet_ntop(AF_INET, &su->sin.sin_addr, buf, len); + #ifdef HAVE_IPV6 case AF_INET6: - snprintf (buf, SU_ADDRSTRLEN, "%s", - inet_ntop (AF_INET6, &(su->sin6.sin6_addr), buf, SU_ADDRSTRLEN)); + return inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, len); break; #endif /* HAVE_IPV6 */ + default: - snprintf (buf, SU_ADDRSTRLEN, "af_unknown %d ", su->sa.sa_family); - break; + snprintf (buf, len, "af_unknown %d ", su->sa.sa_family); + return buf; } - return (XSTRDUP (MTYPE_TMP, buf)); } /* sockunion_connect returns @@ -379,8 +376,10 @@ sockunion_connect (int fd, union sockunion *peersu, unsigned short port, { if (errno != EINPROGRESS) { + char str[SU_ADDRSTRLEN]; zlog_info ("can't connect to %s fd %d : %s", - sockunion_log (&su), fd, safe_strerror (errno)); + sockunion_log (&su, str, sizeof str), + fd, safe_strerror (errno)); return connect_error; } } -- cgit v1.2.1 From 4fafd3deef6eecab229e8b35189ffbc1f1ce9806 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 14:46:42 +0400 Subject: ospfd: avoid redundant lookup in ospf_redistribute_withdraw The old algorithim looked up every node twice as it withdrew the entry. It looks up entry once in redistribute_withdraw, then looks it up again info_delete. Use result of first lookup to do the free directly. This may explain the slow performance observed in https://bugzilla.vyatta.com/show_bug.cgi?id=4421 --- ospfd/ospf_asbr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 6f1b0b06..9d2aedb2 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -285,6 +285,9 @@ ospf_redistribute_withdraw (struct ospf *ospf, u_char type) continue; ospf_external_lsa_flush (ospf, type, &ei->p, ei->ifindex /*, ei->nexthop */); - ospf_external_info_delete (type, ei->p); + + ospf_external_info_free (ei); + route_unlock_node (rn); + rn->info = NULL; } } -- cgit v1.2.1 From 840faaeb00f1617649332dad82952e21e7c7fda7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 14:51:10 +0400 Subject: bgpd: store nexthop info for redistributed IPV6 routes BGP was ignoring nexthop info for static and other redistributed routes for IPv6. Build extra attribute info to store the nexthop. See also: https://bugzilla.vyatta.com/show_bug.cgi?id=6073 --- bgpd/bgp_route.c | 12 +++++++++++- bgpd/bgp_route.h | 4 +++- bgpd/bgp_zebra.c | 27 +++++++++++++++++---------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b7716330..98e49bcd 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5238,7 +5238,8 @@ ALIAS (no_ipv6_aggregate_address_summary_only, /* Redistribute route treatment. */ void -bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, +bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop, + const struct in6_addr *nexthop6, u_int32_t metric, u_char type) { struct bgp *bgp; @@ -5258,6 +5259,15 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, if (nexthop) attr.nexthop = *nexthop; +#ifdef HAVE_IPV6 + if (nexthop6) + { + struct attr_extra *extra = bgp_attr_extra_get(&attr); + extra->mp_nexthop_global = *nexthop6; + extra->mp_nexthop_len = 16; + } +#endif + attr.med = metric; attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3e528596..7adc573b 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -192,7 +192,9 @@ extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *); extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int); -extern void bgp_redistribute_add (struct prefix *, struct in_addr *, u_int32_t, u_char); +extern void bgp_redistribute_add (struct prefix *, const struct in_addr *, + const struct in6_addr *, + u_int32_t, u_char); extern void bgp_redistribute_delete (struct prefix *, u_char); extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index f3baeee0..d7af349a 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -281,7 +281,8 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), api.metric); } - bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type); + bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, + api.metric, api.type); } else { @@ -356,23 +357,29 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) { if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[INET6_ADDRSTRLEN]; - zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u", + char buf[2][INET6_ADDRSTRLEN]; + zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u", zebra_route_string(api.type), - inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)), - p.prefixlen, api.metric); + inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])), + p.prefixlen, + inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), + api.metric); } - bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type); + bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, + api.metric, api.type); } else { if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[INET6_ADDRSTRLEN]; - zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u", + char buf[2][INET6_ADDRSTRLEN]; + zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d " + "nexthop %s metric %u", zebra_route_string(api.type), - inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)), - p.prefixlen, api.metric); + inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])), + p.prefixlen, + inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])), + api.metric); } bgp_redistribute_delete ((struct prefix *) &p, api.type); } -- cgit v1.2.1 From a80e20d17597253e74e22aed6b1a85417f667b49 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 23:54:17 +0400 Subject: ospfd: remove unused code The code for nssa_range and other bits that were written but never used. --- ospfd/ospf_abr.c | 45 -------------------------------------------- ospfd/ospf_route.c | 55 ------------------------------------------------------ ospfd/ospf_spf.c | 2 ++ ospfd/ospf_vty.c | 3 ++- ospfd/ospfd.c | 2 ++ 5 files changed, 6 insertions(+), 101 deletions(-) diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 7e32195b..def55f10 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -614,15 +614,6 @@ set_metric (struct ospf_lsa *lsa, u_int32_t metric) memcpy(header->metric, mp, 3); } -static int -ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost, - struct ospf_area *area) -{ - /* The Type-7 is tested against the aggregated prefix and forwarded - for lsa installation and flooding */ - return 0; -} - /* ospf_abr_translate_nssa */ static int ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) @@ -1577,42 +1568,6 @@ ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */ zlog_debug ("ospf_abr_send_nssa_aggregates(): Stop"); } -static void -ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ -{ - struct listnode *node; - struct ospf_area *area; - - if (! IS_OSPF_ABR (ospf)) - return; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_announce_stub_defaults(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_announce_nssa_defaults(): looking at area %s", - inet_ntoa (area->area_id)); - - if (area->external_routing != OSPF_AREA_NSSA) - continue; - - if (OSPF_IS_AREA_BACKBONE (area)) - continue; /* Sanity Check */ - - /* if (!TranslatorRole continue V 1.0 look for "always" conf */ - if (area->NSSATranslatorState) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_announce_nssa_defaults(): " - "announcing 0.0.0.0/0 to this nssa"); - /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */ - /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/ - } - } -} - static void ospf_abr_announce_stub_defaults (struct ospf *ospf) { diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index d77c7420..d2e5e1e7 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -272,61 +272,6 @@ ospf_route_install (struct ospf *ospf, struct route_table *rt) } } -static void -ospf_intra_route_add (struct route_table *rt, struct vertex *v, - struct ospf_area *area) -{ - struct route_node *rn; - struct ospf_route *or; - struct prefix_ipv4 p; - struct ospf_path *path; - struct vertex_parent *parent; - struct listnode *node, *nnode; - - p.family = AF_INET; - p.prefix = v->id; - if (v->type == OSPF_VERTEX_ROUTER) - p.prefixlen = IPV4_MAX_BITLEN; - else - { - struct network_lsa *lsa = (struct network_lsa *) v->lsa; - p.prefixlen = ip_masklen (lsa->mask); - } - apply_mask_ipv4 (&p); - - rn = route_node_get (rt, (struct prefix *) &p); - if (rn->info) - { - zlog_warn ("Same routing information exists for %s", inet_ntoa (v->id)); - route_unlock_node (rn); - return; - } - - or = ospf_route_new (); - - if (v->type == OSPF_VERTEX_NETWORK) - { - or->type = OSPF_DESTINATION_NETWORK; - - for (ALL_LIST_ELEMENTS (v->parents, node, nnode, parent)) - { - path = ospf_path_new (); - path->nexthop = parent->nexthop->router; - listnode_add (or->paths, path); - } - } - else - or->type = OSPF_DESTINATION_ROUTER; - - or->id = v->id; - or->u.std.area_id = area->area_id; - or->u.std.external_routing= area->external_routing; - or->path_type = OSPF_PATH_INTRA_AREA; - or->cost = v->distance; - - rn->info = or; -} - /* RFC2328 16.1. (4). For "router". */ void ospf_intra_add_router (struct route_table *rt, struct vertex *v, diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 6dcf0b18..d7f9ba27 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1042,6 +1042,7 @@ ospf_rtrs_free (struct route_table *rtrs) route_table_finish (rtrs); } +#if 0 static void ospf_rtrs_print (struct route_table *rtrs) { @@ -1101,6 +1102,7 @@ ospf_rtrs_print (struct route_table *rtrs) zlog_debug ("ospf_rtrs_print() end"); } +#endif /* Calculating the shortest-path tree for an area. */ static void diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index b1526c33..577e4178 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3732,7 +3732,7 @@ show_as_external_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) return 0; } -/* N.B. This function currently seems to be unused. */ +#if 0 static int show_as_external_lsa_stdvty (struct ospf_lsa *lsa) { @@ -3756,6 +3756,7 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa) return 0; } +#endif /* Show AS-NSSA-LSA detail information. */ static int diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index a7553e73..c250fe9e 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1205,6 +1205,7 @@ ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id, return 1; } +#if 0 /* XXX: unused? Leave for symmetry? */ static int ospf_area_nssa_translator_role_unset (struct ospf *ospf, @@ -1222,6 +1223,7 @@ ospf_area_nssa_translator_role_unset (struct ospf *ospf, return 1; } +#endif int ospf_area_export_list_set (struct ospf *ospf, -- cgit v1.2.1 From 8502229b7ed198d994017e4fd04000d429ca9c8d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Dec 2011 00:04:46 +0400 Subject: bgpd: cleanup privs on termination When doing valgrind testing, the privledges from zprivs_init() need to be cleaned up on exit. --- bgpd/bgp_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 778067a8..f835fe77 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -199,6 +199,7 @@ sigint (void) if (! retain_mode) bgp_terminate (); + zprivs_terminate (&bgpd_privs); bgp_exit (0); } -- cgit v1.2.1 From 7e7a2d38b2d5d5edd3be7d6754d67c3231ee215e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Dec 2011 00:09:56 +0400 Subject: zebra: fix warnings in forward proc Check result of fgets(), and don't set variable that is never used. --- zebra/ipforward_proc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c index 73846137..2876eded 100644 --- a/zebra/ipforward_proc.c +++ b/zebra/ipforward_proc.c @@ -45,7 +45,6 @@ ipforward (void) { FILE *fp; int ipforwarding = 0; - char *pnt; char buf[10]; fp = fopen (proc_net_snmp, "r"); @@ -59,8 +58,8 @@ ipforward (void) /* Get ip_statistics.IpForwarding : 1 => ip forwarding enabled 2 => ip forwarding off. */ - pnt = fgets (buf, 6, fp); - sscanf (buf, "Ip: %d", &ipforwarding); + if (fgets (buf, 6, fp)) + sscanf (buf, "Ip: %d", &ipforwarding); fclose(fp); @@ -140,8 +139,8 @@ ipforward_ipv6 (void) if (fp == NULL) return -1; - fgets (buf, 2, fp); - sscanf (buf, "%d", &ipforwarding); + if (fgets (buf, 2, fp)) + sscanf (buf, "%d", &ipforwarding); fclose (fp); return ipforwarding; -- cgit v1.2.1 From 4f5e717413b6627310a245d16f945660c9d60736 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Dec 2011 00:55:15 +0400 Subject: lib: fix SMUX compiler warnings Make progname a string, and cast when calling asn1. Remove variable set but never used. --- lib/smux.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/smux.c b/lib/smux.c index 1941cf8c..b7cd18d1 100644 --- a/lib/smux.c +++ b/lib/smux.c @@ -270,7 +270,6 @@ static void smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat, long errindex, u_char val_type, void *arg, size_t arg_len) { - int ret; u_char buf[BUFSIZ]; u_char *ptr, *h1, *h1e, *h2, *h2e; size_t len, length; @@ -326,7 +325,7 @@ smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat, if (debug_smux) zlog_debug ("SMUX getresp send: %td", (ptr - buf)); - ret = send (smux_sock, buf, (ptr - buf), 0); + send (smux_sock, buf, (ptr - buf), 0); } static u_char * @@ -946,7 +945,7 @@ smux_open (int sock) u_char *ptr; size_t len; long version; - u_char progname[] = QUAGGA_PROGNAME "-" QUAGGA_VERSION; + const char progname[] = QUAGGA_PROGNAME "-" QUAGGA_VERSION; if (debug_smux) { @@ -977,7 +976,7 @@ smux_open (int sock) ptr = asn_build_string (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR), - progname, strlen (progname)); + (const u_char *) progname, strlen (progname)); /* SMUX connection password. */ ptr = asn_build_string (ptr, &len, -- cgit v1.2.1 From 94e7cd90feb6af51b7e21d5289dc0edc1ba94a99 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 7 Dec 2011 01:35:11 +0400 Subject: Revert "lib: address -Wunused-but-set-variable" Stephen Hemminger's commits contain all the changes and several other warning fixes. This reverts commit 6947dbebdc91b6272f8107a6e0dd211457438606. --- lib/distribute.c | 12 ++++++++---- lib/if.c | 6 ++++++ lib/if_rmap.c | 3 ++- lib/vty.c | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/distribute.c b/lib/distribute.c index 056cd401..7f84b80e 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -304,6 +304,7 @@ DEFUN (distribute_list_all, "Filter outgoing routing updates\n") { enum distribute_type type; + struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -318,7 +319,7 @@ DEFUN (distribute_list_all, } /* Get interface name corresponding distribute list. */ - distribute_list_set (NULL, type, argv[0]); + dist = distribute_list_set (NULL, type, argv[0]); return CMD_SUCCESS; } @@ -383,6 +384,7 @@ DEFUN (distribute_list, "Interface name\n") { enum distribute_type type; + struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -396,7 +398,7 @@ DEFUN (distribute_list, } /* Get interface name corresponding distribute list. */ - distribute_list_set (argv[2], type, argv[0]); + dist = distribute_list_set (argv[2], type, argv[0]); return CMD_SUCCESS; } @@ -461,6 +463,7 @@ DEFUN (distribute_list_prefix_all, "Filter outgoing routing updates\n") { enum distribute_type type; + struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -475,7 +478,7 @@ DEFUN (distribute_list_prefix_all, } /* Get interface name corresponding distribute list. */ - distribute_list_prefix_set (NULL, type, argv[0]); + dist = distribute_list_prefix_set (NULL, type, argv[0]); return CMD_SUCCESS; } @@ -543,6 +546,7 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, "Interface name\n") { enum distribute_type type; + struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -557,7 +561,7 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, } /* Get interface name corresponding distribute list. */ - distribute_list_prefix_set (argv[2], type, argv[0]); + dist = distribute_list_prefix_set (argv[2], type, argv[0]); return CMD_SUCCESS; } diff --git a/lib/if.c b/lib/if.c index 41115b0f..d14cfb93 100644 --- a/lib/if.c +++ b/lib/if.c @@ -426,6 +426,9 @@ if_flag_dump (unsigned long flag) static void if_dump (const struct interface *ifp) { + struct listnode *node; + struct connected *c; + zlog_info ("Interface %s index %d metric %d mtu %d " #ifdef HAVE_IPV6 "mtu6 %d " @@ -436,6 +439,9 @@ if_dump (const struct interface *ifp) ifp->mtu6, #endif /* HAVE_IPV6 */ if_flag_dump (ifp->flags)); + + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c)) + ; } /* Interface printing for all interface. */ diff --git a/lib/if_rmap.c b/lib/if_rmap.c index b49d2669..ddc62fd5 100644 --- a/lib/if_rmap.c +++ b/lib/if_rmap.c @@ -212,6 +212,7 @@ DEFUN (if_rmap, "Route map interface name\n") { enum if_rmap_type type; + struct if_rmap *if_rmap; if (strncmp (argv[1], "i", 1) == 0) type = IF_RMAP_IN; @@ -223,7 +224,7 @@ DEFUN (if_rmap, return CMD_WARNING; } - if_rmap_set (argv[2], type, argv[0]); + if_rmap = if_rmap_set (argv[2], type, argv[0]); return CMD_SUCCESS; } diff --git a/lib/vty.c b/lib/vty.c index 83bd6785..d9eb921e 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1685,6 +1685,7 @@ static int vty_accept (struct thread *thread) { int vty_sock; + struct vty *vty; union sockunion su; int ret; unsigned int on; @@ -1769,7 +1770,7 @@ vty_accept (struct thread *thread) if (bufp) XFREE (MTYPE_TMP, bufp); - vty_create (vty_sock, &su); + vty = vty_create (vty_sock, &su); return 0; } -- cgit v1.2.1 From 07bb964ef11d34235570427cd9bc4111956e31b7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Dec 2011 01:29:49 +0400 Subject: lib: fix compile warnings from set-never-used The if_dump code had empty loop, that caused set-never-used warning. --- lib/if.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/if.c b/lib/if.c index d14cfb93..41115b0f 100644 --- a/lib/if.c +++ b/lib/if.c @@ -426,9 +426,6 @@ if_flag_dump (unsigned long flag) static void if_dump (const struct interface *ifp) { - struct listnode *node; - struct connected *c; - zlog_info ("Interface %s index %d metric %d mtu %d " #ifdef HAVE_IPV6 "mtu6 %d " @@ -439,9 +436,6 @@ if_dump (const struct interface *ifp) ifp->mtu6, #endif /* HAVE_IPV6 */ if_flag_dump (ifp->flags)); - - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c)) - ; } /* Interface printing for all interface. */ -- cgit v1.2.1 From 89e9f82e0b717c0e39bbffa104f9d9f817c19b46 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Sun, 11 Dec 2011 18:48:47 +0400 Subject: zebra: ZEBRA_HELLO and mopping up routes (BZ#448) ZEBRA_HELLO message is used by routing daemons to inform zebra what type of routes daemon will be announcing to zebra. Also zebra uses route_type_oaths array to track which daemon announces which protocol. Zebra mops up routes if daemon didn't for some reason. --- lib/zclient.c | 21 ++++++++++++++++++++ lib/zebra.h | 3 ++- zebra/rib.h | 1 + zebra/zebra_rib.c | 36 ++++++++++++++++++++++++++++++++- zebra/zserv.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index a5d5b7ff..37ee2420 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -318,6 +318,25 @@ zebra_message_send (struct zclient *zclient, int command) return zclient_send_message(zclient); } +static int +zebra_hello_send (struct zclient *zclient) +{ + struct stream *s; + + if (zclient->redist_default) + { + s = zclient->obuf; + stream_reset (s); + + zclient_create_header (s, ZEBRA_HELLO); + stream_putc (s, zclient->redist_default); + stream_putw_at (s, 0, stream_get_endp (s)); + return zclient_send_message(zclient); + } + + return 0; +} + /* Make connection to zebra daemon. */ int zclient_start (struct zclient *zclient) @@ -359,6 +378,8 @@ zclient_start (struct zclient *zclient) /* Create read thread. */ zclient_event (ZCLIENT_READ, zclient); + zebra_hello_send (zclient); + /* We need router-id information. */ zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD); diff --git a/lib/zebra.h b/lib/zebra.h index 4b4c7c00..ab072d6e 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -417,7 +417,8 @@ struct in_pktinfo #define ZEBRA_ROUTER_ID_ADD 20 #define ZEBRA_ROUTER_ID_DELETE 21 #define ZEBRA_ROUTER_ID_UPDATE 22 -#define ZEBRA_MESSAGE_MAX 23 +#define ZEBRA_HELLO 23 +#define ZEBRA_MESSAGE_MAX 24 /* Marker value used in new Zserv, in the byte location corresponding * the command value in the old zserv header. To allow old and new diff --git a/zebra/rib.h b/zebra/rib.h index 887ed3c2..20a206ea 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -266,6 +266,7 @@ extern void rib_weed_tables (void); extern void rib_sweep_route (void); extern void rib_close (void); extern void rib_init (void); +extern unsigned long rib_score_proto (u_char proto); extern int static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 8228350f..72633895 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2881,7 +2881,41 @@ rib_sweep_route (void) rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0)); rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0)); } - + +/* Remove specific by protocol routes from 'table'. */ +static unsigned long +rib_score_proto_table (u_char proto, struct route_table *table) +{ + struct route_node *rn; + struct rib *rib; + struct rib *next; + unsigned long n = 0; + + if (table) + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = next) + { + next = rib->next; + if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) + continue; + if (rib->type == proto) + { + rib_delnode (rn, rib); + n++; + } + } + + return n; +} + +/* Remove specific by protocol routes. */ +unsigned long +rib_score_proto (u_char proto) +{ + return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0)) + +rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0)); +} + /* Close RIB and clean up kernel routes. */ static void rib_close_table (struct route_table *table) diff --git a/zebra/zserv.c b/zebra/zserv.c index d558b2d2..ec8cbf2b 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -64,6 +64,15 @@ zserv_delayed_close(struct thread *thread) return 0; } +/* When client connects, it sends hello message + * with promise to send zebra routes of specific type. + * Zebra stores a socket fd of the client into + * this array. And use it to clean up routes that + * client didn't remove for some reasons after closing + * connection. + */ +static int route_type_oaths[ZEBRA_ROUTE_MAX]; + static int zserv_flush_data(struct thread *thread) { @@ -1071,6 +1080,49 @@ zread_router_id_delete (struct zserv *client, u_short length) return 0; } +/* Tie up route-type and client->sock */ +static void +zread_hello (struct zserv *client) +{ + /* type of protocol (lib/zebra.h) */ + u_char proto; + proto = stream_getc (client->ibuf); + + /* accept only dynamic routing protocols */ + if ((proto < ZEBRA_ROUTE_MAX) + && (proto > ZEBRA_ROUTE_STATIC)) + { + zlog_notice ("client %d says hello and bids fair to announce only %s routes", + client->sock, zebra_route_string(proto)); + + /* if route-type was binded by other client */ + if (route_type_oaths[proto]) + zlog_warn ("sender of %s routes changed %c->%c", + zebra_route_string(proto), route_type_oaths[proto], + client->sock); + + route_type_oaths[proto] = client->sock; + } +} + +/* If client sent routes of specific type, zebra removes it + * and returns number of deleted routes. + */ +static void +zebra_score_rib (int client_sock) +{ + int i; + + for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++) + if (client_sock == route_type_oaths[i]) + { + zlog_notice ("client %d disconnected. %lu %s routes removed from the rib", + client_sock, rib_score_proto (i), zebra_route_string (i)); + route_type_oaths[i] = 0; + break; + } +} + /* Close zebra client. */ static void zebra_client_close (struct zserv *client) @@ -1079,6 +1131,7 @@ zebra_client_close (struct zserv *client) if (client->sock) { close (client->sock); + zebra_score_rib (client->sock); client->sock = -1; } @@ -1283,6 +1336,9 @@ zebra_client_read (struct thread *thread) case ZEBRA_IPV4_IMPORT_LOOKUP: zread_ipv4_import_lookup (client, length); break; + case ZEBRA_HELLO: + zread_hello (client); + break; default: zlog_info ("Zebra received unknown command %d", command); break; @@ -1352,6 +1408,7 @@ zebra_serv () return; } + memset (&route_type_oaths, 0, sizeof (route_type_oaths)); memset (&addr, 0, sizeof (struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons (ZEBRA_PORT); @@ -1422,6 +1479,8 @@ zebra_serv_un (const char *path) return; } + memset (&route_type_oaths, 0, sizeof (route_type_oaths)); + /* Make server socket. */ memset (&serv, 0, sizeof (struct sockaddr_un)); serv.sun_family = AF_UNIX; -- cgit v1.2.1 From b31d8fc3016615571f79161b8405aa4033cdfb8d Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Mon, 12 Dec 2011 20:30:10 +0400 Subject: ospfd: fix packet reception for FreeBSD 10. * ospf_packet.c (ospf_recv_packet): FreeBSD, starting from version 10, will not subtract the IP header size from ip_len. This is the patch from FreeBSD's ports/net/quagga/files/patch-ospfd__ospf_packet.c, by Boris Kovalenko. --- ospfd/ospf_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 1c1a1e69..994d3629 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2067,7 +2067,7 @@ ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf) ip_len = iph->ip_len; -#if !defined(GNU_LINUX) && (OpenBSD < 200311) +#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000) /* * Kernel network code touches incoming IP header parameters, * before protocol specific processing. -- cgit v1.2.1 From 45b341f72df6d7dd89133dfd21f43cf1cca74ce5 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 17 Dec 2011 19:39:30 +0400 Subject: bgpd: justify checks for IPv4 class D/E * lib/prefix.h * IPV4_CLASS_DE(): make consistent with counterpart macros * bgp_packet.c * bgp_open_receive(): test using macro instead of ">=" * bgp_route.c * bgp_update_rsclient(): idem * bgp_update_main(): idem --- bgpd/bgp_packet.c | 2 +- bgpd/bgp_route.c | 8 ++++---- lib/prefix.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 5f150600..fc653e21 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1387,7 +1387,7 @@ bgp_open_receive (struct peer *peer, bgp_size_t size) /* remote router-id check. */ if (remote_id.s_addr == 0 - || ntohl (remote_id.s_addr) >= 0xe0000000 + || IPV4_CLASS_DE (ntohl (remote_id.s_addr)) || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr)) { if (BGP_DEBUG (normal, NORMAL)) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 98e49bcd..189929a0 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1815,9 +1815,9 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, /* IPv4 unicast next hop check. */ if (afi == AFI_IP && safi == SAFI_UNICAST) { - /* Next hop must not be 0.0.0.0 nor Class E address. */ + /* Next hop must not be 0.0.0.0 nor Class D/E address. */ if (new_attr.nexthop.s_addr == 0 - || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000) + || IPV4_CLASS_DE (ntohl (new_attr.nexthop.s_addr))) { bgp_attr_unintern (attr_new); @@ -2071,11 +2071,11 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, goto filtered; } - /* Next hop must not be 0.0.0.0 nor Class E address. Next hop + /* Next hop must not be 0.0.0.0 nor Class D/E address. Next hop must not be my own address. */ if (bgp_nexthop_self (afi, &new_attr) || new_attr.nexthop.s_addr == 0 - || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000) + || IPV4_CLASS_DE (ntohl (new_attr.nexthop.s_addr))) { reason = "martian next-hop;"; goto filtered; diff --git a/lib/prefix.h b/lib/prefix.h index 12c0d07e..dab4202e 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -112,7 +112,7 @@ struct prefix_rd #define IPV4_NET0(a) ((((u_int32_t) (a)) & 0xff000000) == 0x00000000) #define IPV4_NET127(a) ((((u_int32_t) (a)) & 0xff000000) == 0x7f000000) #define IPV4_LINKLOCAL(a) ((((u_int32_t) (a)) & 0xffff0000) == 0xa9fe0000) -#define IPV4_CLASS_DE(a) ((u_int32_t) (a) >= 0xe0000000) +#define IPV4_CLASS_DE(a) ((((u_int32_t) (a)) & 0xe0000000) == 0xe0000000) /* Max bit/byte length of IPv6 address. */ #define IPV6_MAX_BYTELEN 16 -- cgit v1.2.1 From 7eed92b9653b09f064e827e887c29ee11122b4fe Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 18 Dec 2011 15:40:17 +0400 Subject: lib: address type-punned pointers in prefix_same() IPV4_ADDR_SAME() wasn't passed the right union member, this could cause a bug due to strict-aliasing. IPV6_ADDR_SAME() case got its fix before the error could be created by macro upgrade. --- lib/prefix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index 23202b62..ceda08de 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -2411,11 +2411,11 @@ prefix_same (const struct prefix *p1, const struct prefix *p2) if (p1->family == p2->family && p1->prefixlen == p2->prefixlen) { if (p1->family == AF_INET) - if (IPV4_ADDR_SAME (&p1->u.prefix, &p2->u.prefix)) + if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr)) return 1; #ifdef HAVE_IPV6 if (p1->family == AF_INET6 ) - if (IPV6_ADDR_SAME (&p1->u.prefix, &p2->u.prefix)) + if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr)) return 1; #endif /* HAVE_IPV6 */ } -- cgit v1.2.1 From 85136e904861775bdf6fbbbd4f0080f06e749bcb Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 18 Dec 2011 16:27:02 +0400 Subject: ospfd: fix bug in NSSA ABR status check * ospf_abr.c * ospf_abr_nssa_am_elected(): feed "best" instead of "address of best" into IPV4_ADDR_CMP(), because "best" is a pointer; also, mean s_addr field of the structures to get better typed pointers --- ospfd/ospf_abr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index def55f10..d06a34ad 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -384,7 +384,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area) if (best == NULL) best = &lsa->data->id; else - if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0) + if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0) best = &lsa->data->id; } @@ -395,7 +395,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area) if (best == NULL) return 1; - if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0) + if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0) return 1; else return 0; -- cgit v1.2.1 From 13351032d1d1632dbaf540cf33b7bebbc748c415 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Tue, 20 Dec 2011 20:52:31 +0400 Subject: ospf6d: add verifying user's privileges --- ospf6d/ospf6_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 235a6858..8444d90f 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -262,6 +262,13 @@ main (int argc, char *argv[], char *envp[]) } } + if (geteuid () != 0) + { + errno = EPERM; + perror (progname); + exit (1); + } + /* thread master */ master = thread_master_create (); -- cgit v1.2.1 From a809d1cc54a621f4b31397ee5b8b79151baa4bf2 Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:00:54 -0800 Subject: lib: Add a function to delete all interfaces if.c: (if_terminate) This adds a cleanup function that can be called when a daemon exits, similar to vty_terminate(). --- lib/if.c | 18 ++++++++++++++++++ lib/if.h | 1 + 2 files changed, 19 insertions(+) diff --git a/lib/if.c b/lib/if.c index 41115b0f..31c60e3f 100644 --- a/lib/if.c +++ b/lib/if.c @@ -872,3 +872,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); -- cgit v1.2.1 From 36d3e8d828e18c5c4cd097f659e3984ff02532cb Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:01:41 -0800 Subject: ospf6d: Have ospf6d cleanup when it terminates normally A clean exit makes it easier to use memory debuggers. * ospf6_asbr.c: (ospf6_asbr_terminate) Add a function to do route map cleanup. * ospf6_lsa.c: (ospf6_lsa_terminate) Add a function to cleanup the lsa handler vector. * ospf6_main.c: (ospf6_exit) Add an function that causes ospf6d to gracefully exit. * ospf6_message.c: (ospf6_message_terminate) Add a function that frees the send and receive buffers. * ospf6_top.c: (ospf6_delete) Enable the ospf6_delete() function. Disable ospf6 before freeing everything. Signed-off-by: Vyacheslav Trushkin Conflicts: ospf6d/ospf6_lsa.h --- ospf6d/ospf6_asbr.c | 5 +++++ ospf6d/ospf6_asbr.h | 1 + ospf6d/ospf6_lsa.c | 5 +++++ ospf6d/ospf6_lsa.h | 1 + ospf6d/ospf6_main.c | 35 ++++++++++++++++++++++++++++++++--- ospf6d/ospf6_message.c | 18 ++++++++++++++++++ ospf6d/ospf6_message.h | 1 + ospf6d/ospf6_top.c | 9 ++++++--- ospf6d/ospf6_top.h | 1 + 9 files changed, 70 insertions(+), 6 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index bc05dc27..ae0a286d 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1275,6 +1275,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 5f072cff..72e49143 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -89,6 +89,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_lsa.c b/ospf6d/ospf6_lsa.c index a9545c33..e65752d8 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -722,6 +722,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 13b89900..7d93f5cb 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -244,6 +244,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 int config_write_ospf6_debug_lsa (struct vty *vty); extern void install_element_ospf6_debug_lsa (void); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 8444d90f..65fcb597 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -131,6 +131,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) @@ -143,7 +172,7 @@ static void sigint (void) { zlog_notice ("Terminating on signal SIGINT"); - exit (0); + ospf6_exit (0); } /* SIGTERM handler. */ @@ -151,7 +180,7 @@ static void sigterm (void) { zlog_notice ("Terminating on signal SIGTERM"); - exit (0); + ospf6_exit (0); } /* SIGUSR1 handler. */ @@ -325,7 +354,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 8179fc14..aaee4d20 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1504,6 +1504,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 87a7cfeb..b085a967 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_top.c b/ospf6d/ospf6_top.c index 38f94d7b..df856b4c 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); -- cgit v1.2.1 From 65cd7a4a66145cf666df707781c3e46297158c58 Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 10 Nov 2010 13:03:02 -0800 Subject: ospf6d: Route locking (memory) cleanup * ospf6_route.c: (ospf6_route_best_next) Allows unlock route, even when there's no next route. This is consistent with how ospf6_route_next() behaves. * ospf6_intra.c: (ospf6_intra_prefix_lsa_remove) Make sure the last route considered is always unlocked. This is needed when the for loop terminates because ospf6_route_is_prefix() returns zero. Signed-off-by: Vyacheslav Trushkin --- ospf6d/ospf6_intra.c | 2 ++ ospf6d/ospf6_route.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) 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_route.c b/ospf6d/ospf6_route.c index 2d027101..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; } -- cgit v1.2.1 From 830526a51292e6241f7b6415e070f3780fe18e1e Mon Sep 17 00:00:00 2001 From: Ulrich Weber Date: Wed, 21 Dec 2011 02:24:11 +0400 Subject: lib: fix some strtoul() use cases ...otherwise 4294967295 is not a valid value on 32bit systems --- bgpd/bgp_mplsvpn.c | 8 ++++++-- bgpd/bgp_routemap.c | 20 ++++++++++++++------ lib/vty.h | 3 ++- ospfd/ospf_vty.c | 5 ++++- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 72ad089e..c1f1fbb3 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -233,9 +233,13 @@ str2tag (const char *str, u_char *tag) char *endptr; u_int32_t t; - l = strtoul (str, &endptr, 10); + if (*str == '-') + return 0; - if (*endptr == '\0' || l == ULONG_MAX || l > UINT32_MAX) + errno = 0; + l = strtoul (str, &endptr, 10); + + if (*endptr != '\0' || errno || l > UINT32_MAX) return 0; t = (u_int32_t) l; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 173bf93b..42c3e053 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -525,8 +525,13 @@ route_match_metric_compile (const char *arg) char *endptr = NULL; unsigned long tmpval; + /* Metric value shoud be integer. */ + if (! all_digit (arg)) + return NULL; + + errno = 0; tmpval = strtoul (arg, &endptr, 10); - if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX) + if (*endptr != '\0' || errno || tmpval > UINT32_MAX) return NULL; med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); @@ -1002,8 +1007,9 @@ route_set_local_pref_compile (const char *arg) if (! all_digit (arg)) return NULL; + errno = 0; tmp = strtoul (arg, &endptr, 10); - if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX) + if (*endptr != '\0' || errno || tmp > UINT32_MAX) return NULL; local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); @@ -1070,9 +1076,9 @@ route_set_weight_compile (const char *arg) if (! all_digit (arg)) return NULL; - + errno = 0; tmp = strtoul (arg, &endptr, 10); - if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX) + if (*endptr != '\0' || errno || tmp > UINT32_MAX) return NULL; weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); @@ -1161,8 +1167,9 @@ route_set_metric_compile (const char *arg) if (all_digit (arg)) { /* set metric value check*/ + errno = 0; larg = strtoul (arg, &endptr, 10); - if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX) + if (*endptr != '\0' || errno || larg > UINT32_MAX) return NULL; metric = larg; } @@ -1174,8 +1181,9 @@ route_set_metric_compile (const char *arg) || (! all_digit (arg+1))) return NULL; + errno = 0; larg = strtoul (arg+1, &endptr, 10); - if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX) + if (*endptr != '\0' || errno || larg > UINT32_MAX) return NULL; metric = larg; } diff --git a/lib/vty.h b/lib/vty.h index 7df04b5f..639d7417 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -152,8 +152,9 @@ struct vty #define VTY_GET_LONG(NAME,V,STR) \ do { \ char *endptr = NULL; \ + errno = 0; \ (V) = strtoul ((STR), &endptr, 10); \ - if (*endptr != '\0' || (V) == ULONG_MAX) \ + if (*(STR) == '-' || *endptr != '\0' || errno) \ { \ vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \ return CMD_WARNING; \ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 577e4178..f68adb2d 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -80,8 +80,11 @@ ospf_str2area_id (const char *str, struct in_addr *area_id, int *format) /* match "<0-4294967295>". */ else { + if (*str == '-') + return -1; + errno = 0; ret = strtoul (str, &endptr, 10); - if (*endptr != '\0' || (ret == ULONG_MAX && errno == ERANGE)) + if (*endptr != '\0' || errno || ret > UINT32_MAX) return -1; area_id->s_addr = htonl (ret); -- cgit v1.2.1 From b4b315989f9f73bdab4224eb3df80781fa986143 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Thu, 22 Dec 2011 18:24:19 +0400 Subject: ospf6d: fix compiler warning messages * fix disagreement with C99 in zlog_debug calls Format specifier in some zlog_debug calls for size_t values was changed in order to C99 ('%u' -> '%zu'). * fix -Wsign-compare warnings Type of return value of ospf6_packet_max() was changed. --- ospf6d/ospf6_message.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index aaee4d20..01d61263 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1104,7 +1104,7 @@ ospf6_lsaseq_examin if (length < OSPF6_LSA_HEADER_SIZE) { if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%u B) trailing (#%u) LSA header", + zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header", __func__, length, counted_lsas); return MSG_NG; } @@ -1136,7 +1136,7 @@ ospf6_lsaseq_examin if (lsalen > length) { if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %u B", + zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B", __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length); return MSG_NG; } @@ -1707,10 +1707,11 @@ ospf6_send (struct in6_addr *src, struct in6_addr *dst, zlog_err ("Could not send entire message"); } -static int +static uint32_t ospf6_packet_max(struct ospf6_interface *oi) { - return oi->ifmtu - sizeof(struct ip6_hdr); + assert (oi->ifmtu > sizeof (struct ip6_hdr)); + return oi->ifmtu - (sizeof (struct ip6_hdr)); } int -- cgit v1.2.1 From 6dd6c307bf697184a77fd777c0226399de630be5 Mon Sep 17 00:00:00 2001 From: Matthias Ferdinand Date: Mon, 26 Dec 2011 16:35:30 +0400 Subject: zebra: fix ifindex test condition (BZ#487) When the same ip address is used on several interfaces, and one of them gets deleted (or equivalent: set to down and then address removed), rib_delete_ipv[46] will also remove the connected route from other interfaces. rib_delete_ipv[46] is called twice when an interface is deleted: - for the "ifdown" event - for the address removal (note: this may be specific to the netlink interface of linux) The second call does not find the connected route to that same ifindex anymore, but deletes similar connected routes to any other ifindex instead. Reason: the ifindex check is on the same level as the check for ZEBRA_ROUTE_CONNECT/NEXTHOP_TYPE_IFINDEX. If everything matches except for the ifindex, the "else" part (intended for different route types) is executed, thus removing the route from the wrong interface. fix: move ifindex check inside the "then" part of the check for ZEBRA_ROUTE_CONNECT/NEXTHOP_TYPE_IFINDEX. Now connected routes to other ifindexes will not spill over to the "else" part for different route types anymore. --- zebra/zebra_rib.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 72633895..d239501d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1883,8 +1883,10 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p, if (rib->type != type) continue; if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) && - nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex) + nexthop->type == NEXTHOP_TYPE_IFINDEX) { + if (nexthop->ifindex != ifindex) + continue; if (rib->refcnt) { rib->refcnt--; @@ -2431,8 +2433,10 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p, if (rib->type != type) continue; if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) && - nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex) + nexthop->type == NEXTHOP_TYPE_IFINDEX) { + if (nexthop->ifindex != ifindex) + continue; if (rib->refcnt) { rib->refcnt--; -- cgit v1.2.1 From 2894cdc344ab15d8a80906d77cfe90378f82f71d Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 27 Dec 2011 10:18:47 +0400 Subject: zebra: fix IPv6 RA wrt interface removal (BZ#480) --- zebra/rtadv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 8cc3c4cb..3e8750aa 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -368,7 +368,7 @@ rtadv_timer (struct thread *thread) for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp)) { - if (if_is_loopback (ifp)) + if (if_is_loopback (ifp) || ! if_is_operative (ifp)) continue; zif = ifp->info; -- cgit v1.2.1 From f382ad5696a2b0d4cc1dd16752638c9c4dc2b2f8 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 27 Dec 2011 18:06:45 +0400 Subject: doc: update BGP RFC references --- doc/BGP-TypeCode | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/doc/BGP-TypeCode b/doc/BGP-TypeCode index 5663c4d7..b3218079 100644 --- a/doc/BGP-TypeCode +++ b/doc/BGP-TypeCode @@ -3,24 +3,22 @@ Value Attribute References ========================================================================= - 1 ORIGIN [RFC 1771] - 2 AS_PATH [RFC 1771] - 3 NEXT_HOP [RFC 1771] - 4 MULTI_EXIT_DISC [RFC 1771] - 5 LOCAL_PREF [RFC 1771] - 6 ATOMIC_AGGREGATE [RFC 1771] - 7 AGGREGATOR [RFC 1771] + 1 ORIGIN [RFC 4271] + 2 AS_PATH [RFC 4271] + 3 NEXT_HOP [RFC 4271] + 4 MULTI_EXIT_DISC [RFC 4271] + 5 LOCAL_PREF [RFC 4271] + 6 ATOMIC_AGGREGATE [RFC 4271] + 7 AGGREGATOR [RFC 4271] 8 COMMUNITIES [RFC 1997] - 9 ORIGINATOR_ID [RFC 1966] - 10 CLUSTER_LIST [RFC 1966] + 9 ORIGINATOR_ID [RFC 4456] + 10 CLUSTER_LIST [RFC 4456] 11 DPA [draft-ietf-idr-bgp-dpa-05.txt(expired)] - 12 ADVERTISER [Changed from RFC 1863 bgp@ans.net ML?] - 13 RCID_PATH [Changed from RFC 1863 bgp@ans.net ML?] - 14 MP_REACH_NLRI [RFC 2283] - 15 MP_UNREACH_NLRI [RFC 2283] - 16 EXT_COMMUNITIES [draft-ramachandra-bgp-ext-communities-09.txt] + 12 ADVERTISER [RFC 1863] + 13 RCID_PATH [RFC 1863] + 14 MP_REACH_NLRI [RFC 4760] + 15 MP_UNREACH_NLRI [RFC 4760] + 16 EXT_COMMUNITIES [RFC 4360] 17 AS4_PATH [RFC 4893] 18 AS4_AGGREGATOR [RFC 4893] - 254 RCID_PATH [RFC 1863] - 255 ADVERTISER [RFC 1863] ========================================================================= -- cgit v1.2.1 From 708a758fb8013d4b40ae09f81e4c5830279bf10c Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 5 Jan 2012 17:46:53 +0400 Subject: version RE-0.99.17.6 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9536443c..676c5dcc 100755 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.17.5, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.17.6, [https://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) -- cgit v1.2.1