From d91f35bc90ec4e5c8513cd7ac1f6fd00c5113c27 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(-) (limited to 'ospf6d') 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 ef95122eb214f80700fc79b4a95686eadfea859b 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 51933b76..f4df318b 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -225,8 +225,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 a0bf59bcac8b40c3f83e7f2e7f65087ece6acfc7 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(+) (limited to 'ospf6d') 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 09395e2a0e93b2cf4258cb1de91887948796bb68 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 588b9462..e65752d8 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 abc7ef44ca05493500865ce81f7b84f5c4eb6594 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(-) (limited to 'ospf6d') 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 6deb93ef..cd1c939a 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -44,6 +44,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 c1093cab..a2991ba7 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 f4df318b..f40ad4b0 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" @@ -46,6 +51,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 @@ -224,52 +257,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) @@ -281,9 +268,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)); @@ -815,9 +799,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) { @@ -867,9 +848,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) { @@ -944,6 +922,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) @@ -953,9 +1358,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) { @@ -1033,8 +1435,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) @@ -1217,11 +1617,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) @@ -1229,8 +1624,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)) @@ -1267,14 +1676,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 c72f0af4..232b875e 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 75d044d234d1826db729f9ca580c966a028dbfc3 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index f4b327e4..7d8824d7 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -441,14 +441,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 @@ -457,7 +457,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); } @@ -483,11 +483,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; @@ -500,7 +500,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 5fdaa04e635fdef7deca9bdfe1be4b60ec90add6 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(+) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 7d8824d7..9934e6b9 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -420,6 +420,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 ea4021984f9eec3f2a85551ae0822e1dff0ed2bc 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(-) (limited to 'ospf6d') 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 2b65be82..df856b4c 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -594,10 +594,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, @@ -607,10 +607,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 87362ceb5d493f12e8c937b533190a1996d2df22 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index cd1c939a..6aab1df0 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 800fae4b..0e613152 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 cb549618..beb6d7f7 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 6d0732c8abad7ace509d033a41814ea03a3a1b16 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 --- ospf6d/ospf6_network.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'ospf6d') 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 */ -- cgit v1.2.1 From 681b84e8f50a09ff871d9e6536e8d8afb115ce13 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index f40ad4b0..42521a2d 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -47,6 +47,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" }; @@ -1774,6 +1776,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) { @@ -1820,7 +1828,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"); @@ -1896,7 +1904,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; @@ -1930,7 +1938,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; @@ -1997,7 +2005,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; @@ -2066,7 +2074,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; @@ -2086,7 +2094,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; @@ -2159,7 +2167,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; @@ -2226,7 +2234,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. */ @@ -2286,7 +2294,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 c143c38bc707194d52aec544e62e5485c6c4bc08 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Dec 2011 01:25:46 +0400 Subject: ospf6d: fix compile warning from falling off end of main ospf6 main always calls ospf6_exit() which always calls exit. Use attributes to tell GCC that this is ok. --- ospf6d/ospf6_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 0e613152..6f7717c8 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -129,7 +129,7 @@ Report bugs to zebra@zebra.org\n", progname); exit (status); } -static void +static void __attribute__ ((noreturn)) ospf6_exit (int status) { extern struct ospf6 *ospf6; -- cgit v1.2.1 From 42a7debf3c76b8001ce820e104a29d2f693c7cb7 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(+) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 3efaab44..922e1c0e 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); @@ -813,6 +814,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) @@ -990,6 +1039,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, @@ -1082,6 +1164,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); @@ -1090,6 +1174,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 6aab1df0..72e49143 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 9a9446eabb8f153251d6d93d225a68ca44b436ac 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(-) (limited to 'ospf6d') 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 b51146856e660bcec723f535c17dc1c38b2f6efc 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. --- ospf6d/ospf6_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 6f7717c8..c4b9124e 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\ @@ -231,7 +233,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; @@ -252,6 +254,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... */ -- cgit v1.2.1 From 05e54ee3df973194f2a00e3ea0b1da7bebc71fd6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 3 Dec 2011 17:45:17 +0400 Subject: build: delete .cvsignore files --- ospf6d/.cvsignore | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 ospf6d/.cvsignore (limited to 'ospf6d') 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 -- cgit v1.2.1 From e0ca5fde7be5b5ce90dae78c2477e8245aecb8e9 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 --- ospf6d/ospf6_asbr.c | 75 +++++++++++++++-------------------------------------- 1 file changed, 21 insertions(+), 54 deletions(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 922e1c0e..ae0a286d 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -617,27 +617,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); @@ -647,29 +636,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]); @@ -679,28 +657,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); -- cgit v1.2.1 From fa0796661c9cd68f20882ceb16e9d304a12a6acd 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 42521a2d..0cd90360 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; @@ -1652,8 +1580,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) { @@ -1673,8 +1599,7 @@ ospf6_receive (struct thread *thread) ospf6_lsack_print (oh); break; default: - zlog_debug ("Unknown message"); - break; + assert (0); } } @@ -1701,9 +1626,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 5031ed1347191ee3e0767cfa44e7047c36d37bd1 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 0cd90360..aaee4d20 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; } @@ -1577,7 +1585,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); @@ -1665,7 +1673,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 232b875e..b085a967 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 b48cebbba0dc01ad7d1fbd7cbcc39a11e1ae972d Mon Sep 17 00:00:00 2001 From: Tom Goff Date: Wed, 14 Dec 2011 14:11:29 +0400 Subject: ospf6d: always remove the result of a previous SPF calculation This is needed to avoid stale routes in some cases; the regression was introduced by commit 1d19234e79c77a7d55194b513f2a77c6a691bc2c. * ospf6_spf.c: (ospf6_spf_calculation) Call ospf6_spf_table_finish() before possibly returning if no router-LSA is found for the root of the SPF tree. --- ospf6d/ospf6_spf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index beb6d7f7..a4a5b721 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -391,6 +391,8 @@ ospf6_spf_calculation (u_int32_t router_id, caddr_t lsdesc; struct ospf6_lsa *lsa; + ospf6_spf_table_finish (result_table); + /* Install the calculating router itself as the root of the SPF tree */ /* construct root vertex */ lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_ROUTER), htonl (0), @@ -402,8 +404,6 @@ ospf6_spf_calculation (u_int32_t router_id, candidate_list = pqueue_create (); candidate_list->cmp = ospf6_vertex_cmp; - ospf6_spf_table_finish (result_table); - root = ospf6_vertex_create (lsa); root->area = oa; root->cost = 0; -- cgit v1.2.1 From 6fd16207fee6d4d09f29ed7ecf26303a7220e473 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(+) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index c4b9124e..d40bd97f 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -291,6 +291,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 cba1fab2d7e22921a03b8b886772daec8b5977c4 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(-) (limited to 'ospf6d') 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 5e1731ac1d8593c1317d5d907eda62b52b17470f 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(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index a2991ba7..7d93f5cb 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -245,7 +245,6 @@ extern struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type); extern void ospf6_lsa_init (void); extern void ospf6_lsa_terminate (void); -extern void ospf6_lsa_cmd_init (void); extern int config_write_ospf6_debug_lsa (struct vty *vty); extern void install_element_ospf6_debug_lsa (void); -- cgit v1.2.1 From b4e45f67057be22133b6bec88cdf285d5c8214db Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 5 Dec 2011 16:35:14 +0400 Subject: fix zebra protocol after MP-BGP changes The previous commits modified both zebra and bgpd for additional SAFI field, but not any other routing daemon, which led to zebra daemon crashing with failed assertion. --- ospf6d/ospf6_zebra.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 881771a7..f09e9d22 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -451,6 +451,7 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request) api.type = ZEBRA_ROUTE_OSPF6; api.flags = 0; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = nhcount; api.nexthop = nexthops; -- cgit v1.2.1 From 4c0cf00afc4340a429a9c4830f638b4593d7c3af Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 31 May 2010 12:02:31 +0200 Subject: ospf6d: fix out of bounds write in ospf6_prefix_apply_mask ospf6_prefix_apply_mask would write one byte beyond the 4/8/12 bytes allocated for prefixes of length 32/64/96. based on report and patch by Jon Andersson Reported-by: Jon Andersson Signed-off-by: David Lamparter --- ospf6d/ospf6_proto.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_proto.c b/ospf6d/ospf6_proto.c index c792aa45..d011601f 100644 --- a/ospf6d/ospf6_proto.c +++ b/ospf6d/ospf6_proto.c @@ -42,11 +42,10 @@ ospf6_prefix_apply_mask (struct ospf6_prefix *op) return; } - if (index == 16) - return; - - pnt[index] &= mask; - index ++; + /* nonzero mask means no check for this byte because if it contains + * prefix bits it must be there for us to write */ + if (mask) + pnt[index++] &= mask; while (index < OSPF6_PREFIX_SPACE (op->prefix_length)) pnt[index++] = 0; -- cgit v1.2.1 From ef2d5d100431031c32ea35b3c834b46cff16f511 Mon Sep 17 00:00:00 2001 From: Phil Laverdiere Date: Mon, 2 Jan 2012 20:04:26 +0400 Subject: ospf6d: remove own routes on SIGTERM (BZ#448) --- ospf6d/ospf6_main.c | 1 + ospf6d/ospf6_route.h | 1 + ospf6d/ospf6d.c | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index d40bd97f..d3ef0a6a 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -180,6 +180,7 @@ static void sigterm (void) { zlog_notice ("Terminating on signal SIGTERM"); + ospf6_clean(); ospf6_exit (0); } diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index 8dcc877f..b384824c 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -300,6 +300,7 @@ extern void ospf6_brouter_show (struct vty *vty, struct ospf6_route *route); extern int config_write_ospf6_debug_route (struct vty *vty); extern void install_element_ospf6_debug_route (void); extern void ospf6_route_init (void); +extern void ospf6_clean (void); #endif /* OSPF6_ROUTE_H */ diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index bb091d4f..3fdbda18 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -1889,4 +1889,11 @@ ospf6_init (void) thread_add_read (master, ospf6_receive, NULL, ospf6_sock); } - +void +ospf6_clean (void) +{ + if (ospf6->route_table) + ospf6_route_remove_all (ospf6->route_table); + if (ospf6->brouter_table) + ospf6_route_remove_all (ospf6->brouter_table); +} -- cgit v1.2.1 From b51a3a31500133e3e26f12e7639f297c655bc735 Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Fri, 10 Feb 2012 10:42:45 +0400 Subject: ospf6d: remove defaults from iface config (BZ#550) --- ospf6d/ospf6_interface.c | 59 +++++++++++++++++++++++++++++------------------- ospf6d/ospf6_interface.h | 9 ++++++++ 2 files changed, 45 insertions(+), 23 deletions(-) (limited to 'ospf6d') diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index f6420513..71aa6859 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -108,14 +108,14 @@ ospf6_interface_create (struct interface *ifp) oi->neighbor_list = list_new (); oi->neighbor_list->cmp = ospf6_neighbor_cmp; oi->linklocal_addr = (struct in6_addr *) NULL; - oi->instance_id = 0; - oi->transdelay = 1; - oi->priority = 1; - - oi->hello_interval = 10; - oi->dead_interval = 40; - oi->rxmt_interval = 5; - oi->cost = 1; + oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID; + oi->transdelay = OSPF6_INTERFACE_TRANSDELAY; + oi->priority = OSPF6_INTERFACE_PRIORITY; + + oi->hello_interval = OSPF6_INTERFACE_HELLO_INTERVAL; + oi->dead_interval = OSPF6_INTERFACE_DEAD_INTERVAL; + oi->rxmt_interval = OSPF6_INTERFACE_RXMT_INTERVAL; + oi->cost = OSPF6_INTERFACE_COST; oi->state = OSPF6_INTERFACE_DOWN; oi->flag = 0; oi->mtu_ignore = 0; @@ -1522,23 +1522,36 @@ config_write_ospf6_interface (struct vty *vty) if (ifp->desc) vty_out (vty, " description %s%s", ifp->desc, VNL); - if (ifp->mtu6 != oi->ifmtu) vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL); - vty_out (vty, " ipv6 ospf6 cost %d%s", - oi->cost, VNL); - vty_out (vty, " ipv6 ospf6 hello-interval %d%s", - oi->hello_interval, VNL); - vty_out (vty, " ipv6 ospf6 dead-interval %d%s", - oi->dead_interval, VNL); - vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s", - oi->rxmt_interval, VNL); - vty_out (vty, " ipv6 ospf6 priority %d%s", - oi->priority, VNL); - vty_out (vty, " ipv6 ospf6 transmit-delay %d%s", - oi->transdelay, VNL); - vty_out (vty, " ipv6 ospf6 instance-id %d%s", - oi->instance_id, VNL); + + if (oi->cost != OSPF6_INTERFACE_COST) + vty_out (vty, " ipv6 ospf6 cost %d%s", + oi->cost, VNL); + + if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL) + vty_out (vty, " ipv6 ospf6 hello-interval %d%s", + oi->hello_interval, VNL); + + if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL) + vty_out (vty, " ipv6 ospf6 dead-interval %d%s", + oi->dead_interval, VNL); + + if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL) + vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s", + oi->rxmt_interval, VNL); + + if (oi->priority != OSPF6_INTERFACE_PRIORITY) + vty_out (vty, " ipv6 ospf6 priority %d%s", + oi->priority, VNL); + + if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY) + vty_out (vty, " ipv6 ospf6 transmit-delay %d%s", + oi->transdelay, VNL); + + if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID) + vty_out (vty, " ipv6 ospf6 instance-id %d%s", + oi->instance_id, VNL); if (oi->plist_name) vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s", diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index cf758c07..2d1ff34d 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -124,6 +124,15 @@ extern const char *ospf6_interface_state_str[]; #define OSPF6_INTERFACE_DISABLE 0x01 #define OSPF6_INTERFACE_PASSIVE 0x02 +/* default values */ +#define OSPF6_INTERFACE_HELLO_INTERVAL 10 +#define OSPF6_INTERFACE_DEAD_INTERVAL 40 +#define OSPF6_INTERFACE_RXMT_INTERVAL 5 +#define OSPF6_INTERFACE_COST 1 +#define OSPF6_INTERFACE_PRIORITY 1 +#define OSPF6_INTERFACE_TRANSDELAY 1 +#define OSPF6_INTERFACE_INSTANCE_ID 0 + /* Function Prototypes */ -- cgit v1.2.1