| 
									
										
										
										
											2000-03-30 20:00:42 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *	BIRD -- OSPF | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  |  *	(c) 2000--2004 Ondrej Filip <feela@network.cz> | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |  *	(c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org> | 
					
						
							|  |  |  |  *	(c) 2009--2014 CZ.NIC z.s.p.o. | 
					
						
							| 
									
										
										
										
											2000-03-30 20:00:42 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *	Can be freely distributed and used under the terms of the GNU GPL. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ospf.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | struct ospf_lsupd_packet | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   struct ospf_packet hdr; | 
					
						
							|  |  |  |   // union ospf_auth auth;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   u32 lsa_count; | 
					
						
							|  |  |  |   void lsas[]; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | void | 
					
						
							|  |  |  | ospf_dump_lsahdr(struct ospf_proto *p, struct ospf_lsa_header *lsa_n) | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   struct ospf_lsa_header lsa; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   u32 lsa_etype; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   lsa_ntoh_hdr(lsa_n, &lsa); | 
					
						
							|  |  |  |   lsa_etype = lsa_get_etype(&lsa, p); | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   log(L_TRACE "%s:     LSA      Type: %04x, Id: %R, Rt: %R, Seq: %08x, Age: %u, Sum: %04x", | 
					
						
							|  |  |  |       p->p.name, lsa_etype, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum); | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | void | 
					
						
							|  |  |  | ospf_dump_common(struct ospf_proto *p, struct ospf_packet *pkt) | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   log(L_TRACE "%s:     length   %d", p->p.name, ntohs(pkt->length)); | 
					
						
							|  |  |  |   log(L_TRACE "%s:     router   %R", p->p.name, ntohl(pkt->routerid)); | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline uint | 
					
						
							|  |  |  | ospf_lsupd_hdrlen(struct ospf_proto *p) | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   return ospf_pkt_hdrlen(p) + 4; /* + u32 lsa count field */ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline u32 | 
					
						
							|  |  |  | ospf_lsupd_get_lsa_count(struct ospf_packet *pkt, uint hdrlen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   u32 *c = ((void *) pkt) + hdrlen - 4; | 
					
						
							|  |  |  |   return ntohl(*c); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline void | 
					
						
							|  |  |  | ospf_lsupd_set_lsa_count(struct ospf_packet *pkt, uint hdrlen, u32 val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   u32 *c = ((void *) pkt) + hdrlen - 4; | 
					
						
							|  |  |  |   *c = htonl(val); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-06-20 07:37:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline void | 
					
						
							|  |  |  | ospf_lsupd_body(struct ospf_proto *p, struct ospf_packet *pkt, | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | 		uint *offset, uint *lsa_count) | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   uint hlen = ospf_lsupd_hdrlen(p); | 
					
						
							|  |  |  |   *offset = hlen; | 
					
						
							|  |  |  |   *lsa_count = ospf_lsupd_get_lsa_count(pkt, hlen); | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static void | 
					
						
							|  |  |  | ospf_dump_lsupd(struct ospf_proto *p, struct ospf_packet *pkt) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   uint offset, plen, i, lsa_count, lsa_len; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   ASSERT(pkt->type == LSUPD_P); | 
					
						
							|  |  |  |   ospf_dump_common(p, pkt); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   plen = ntohs(pkt->length); | 
					
						
							|  |  |  |   ospf_lsupd_body(p, pkt, &offset, &lsa_count); | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   for (i = 0; i < lsa_count; i++) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     if ((offset + sizeof(struct ospf_lsa_header)) > plen) | 
					
						
							|  |  |  |       goto invalid; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     struct ospf_lsa_header *lsa = ((void *) pkt) + offset; | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     lsa_len = ntohs(lsa->length); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header))) | 
					
						
							|  |  |  |       goto invalid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ospf_dump_lsahdr(p, lsa); | 
					
						
							|  |  |  |     offset += lsa_len; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | invalid: | 
					
						
							|  |  |  |   log(L_TRACE "%s:     LSA      invalid", p->p.name); | 
					
						
							|  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2009-08-27 18:25:46 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | static inline void | 
					
						
							|  |  |  | ospf_lsa_lsrq_down(struct top_hash_entry *req, struct ospf_neighbor *n, struct ospf_neighbor *from) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (req == n->lsrqi) | 
					
						
							|  |  |  |     n->lsrqi = SNODE_NEXT(req); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   s_rem_node(SNODE req); | 
					
						
							|  |  |  |   ospf_hash_delete(n->lsrqh, req); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (EMPTY_SLIST(n->lsrql)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     tm_stop(n->lsrq_timer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (n->state == NEIGHBOR_LOADING) | 
					
						
							|  |  |  |       ospf_neigh_sm(n, INM_LOADDONE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline void | 
					
						
							|  |  |  | ospf_lsa_lsrt_up(struct top_hash_entry *en, struct ospf_neighbor *n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct top_hash_entry *ret = ospf_hash_get_entry(n->lsrth, en); | 
					
						
							| 
									
										
										
										
											2012-10-29 20:29:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   if (!SNODE_VALID(ret)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     en->ret_count++; | 
					
						
							|  |  |  |     s_add_tail(&n->lsrtl, SNODE ret); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |   ret->lsa = en->lsa; | 
					
						
							|  |  |  |   ret->lsa_body = LSA_BODY_DUMMY; | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!tm_active(n->lsrt_timer)) | 
					
						
							|  |  |  |     tm_start(n->lsrt_timer, n->ifa->rxmtint); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | ospf_lsa_lsrt_down_(struct top_hash_entry *en, struct ospf_neighbor *n, struct top_hash_entry *ret) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (en) | 
					
						
							|  |  |  |     en->ret_count--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   s_rem_node(SNODE ret); | 
					
						
							|  |  |  |   ospf_hash_delete(n->lsrth, ret); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (EMPTY_SLIST(n->lsrtl)) | 
					
						
							|  |  |  |     tm_stop(n->lsrt_timer); | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline int | 
					
						
							|  |  |  | ospf_lsa_lsrt_down(struct top_hash_entry *en, struct ospf_neighbor *n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct top_hash_entry *ret = ospf_hash_find_entry(n->lsrth, en); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   if (ret) | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     ospf_lsa_lsrt_down_(en, n, ret); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   return ret != NULL; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  | void | 
					
						
							|  |  |  | ospf_add_flushed_to_lsrt(struct ospf_proto *p, struct ospf_neighbor *n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct top_hash_entry *en; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WALK_SLIST(en, p->lsal) | 
					
						
							|  |  |  |     if ((en->lsa.age == LSA_MAXAGE) && (en->lsa_body != NULL) && | 
					
						
							|  |  |  | 	lsa_flooding_allowed(en->lsa_type, en->domain, n->ifa)) | 
					
						
							|  |  |  |       ospf_lsa_lsrt_up(en, n); | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* If we found any flushed LSA, we send them ASAP */ | 
					
						
							|  |  |  |   if (tm_active(n->lsrt_timer)) | 
					
						
							|  |  |  |     tm_start(n->lsrt_timer, 0); | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | static int ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | ospf_enqueue_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (ifa->flood_queue_used == ifa->flood_queue_size) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* If we already have full queue, we send some packets */ | 
					
						
							|  |  |  |     uint sent = ospf_flood_lsupd(p, ifa->flood_queue, ifa->flood_queue_used, ifa->flood_queue_used / 2, ifa); | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < sent; i++) | 
					
						
							|  |  |  |       ifa->flood_queue[i]->ret_count--; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     ifa->flood_queue_used -= sent; | 
					
						
							|  |  |  |     memmove(ifa->flood_queue, ifa->flood_queue + sent, ifa->flood_queue_used * sizeof(void *)); | 
					
						
							|  |  |  |     bzero(ifa->flood_queue + ifa->flood_queue_used, sent * sizeof(void *)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   en->ret_count++; | 
					
						
							|  |  |  |   ifa->flood_queue[ifa->flood_queue_used] = en; | 
					
						
							|  |  |  |   ifa->flood_queue_used++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!ev_active(p->flood_event)) | 
					
						
							|  |  |  |     ev_schedule(p->flood_event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | ospf_flood_event(void *ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct ospf_proto *p = ptr; | 
					
						
							|  |  |  |   struct ospf_iface *ifa; | 
					
						
							|  |  |  |   int i, count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WALK_LIST(ifa, p->iface_list) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (ifa->flood_queue_used == 0) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     count = ifa->flood_queue_used; | 
					
						
							|  |  |  |     ospf_flood_lsupd(p, ifa->flood_queue, count, count, ifa); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < count; i++) | 
					
						
							|  |  |  |       ifa->flood_queue[i]->ret_count--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ifa->flood_queue_used = 0; | 
					
						
							|  |  |  |     bzero(ifa->flood_queue, count * sizeof(void *)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |  * ospf_flood_lsa - send LSA to the neighbors | 
					
						
							|  |  |  |  * @p: OSPF protocol instance | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |  * @en: LSA entry | 
					
						
							|  |  |  |  * @from: neighbor than sent this LSA (or NULL if LSA is local) | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-06-04 14:03:30 +00:00
										 |  |  |  * return value - was the LSA flooded back? | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-04-18 21:40:11 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  | ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   struct ospf_iface *ifa; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   struct ospf_neighbor *n; | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |   /* RFC 2328 13.3 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   int back = 0; | 
					
						
							|  |  |  |   WALK_LIST(ifa, p->iface_list) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  |     if (ifa->stub) | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2000-09-04 21:21:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     if (! lsa_flooding_allowed(en->lsa_type, en->domain, ifa)) | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2009-01-11 12:14:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-23 16:51:28 +02:00
										 |  |  |     DBG("Wanted to flood LSA: Type: %u, ID: %R, RT: %R, SN: 0x%x, Age %u\n", | 
					
						
							|  |  |  | 	hh->type, hh->id, hh->rt, hh->sn, hh->age); | 
					
						
							| 
									
										
										
										
											2009-01-11 12:14:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     int used = 0; | 
					
						
							|  |  |  |     WALK_LIST(n, ifa->neigh_list) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |       /* 13.3 (1a) */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (n->state < NEIGHBOR_EXCHANGE) | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* 13.3 (1b) */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (n->state < NEIGHBOR_FULL) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	struct top_hash_entry *req = ospf_hash_find_entry(n->lsrqh, en); | 
					
						
							|  |  |  | 	if (req != NULL) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	  int cmp = lsa_comp(&en->lsa, &req->lsa); | 
					
						
							| 
									
										
										
										
											2009-01-11 12:14:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	  /* If same or newer, remove LSA from the link state request list */ | 
					
						
							|  |  |  | 	  if (cmp > CMP_OLDER) | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | 	    ospf_lsa_lsrq_down(req, n, from); | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  /* If older or same, skip processing of this neighbor */ | 
					
						
							|  |  |  | 	  if (cmp < CMP_NEWER) | 
					
						
							|  |  |  | 	    continue; | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |       /* 13.3 (1c) */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (n == from) | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* In OSPFv3, there should be check whether receiving router understand
 | 
					
						
							|  |  |  | 	 that type of LSA (for LSA types with U-bit == 0). But as we do not support | 
					
						
							|  |  |  | 	 any optional LSA types, this is not needed yet */ | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* 13.3 (1d) - add LSA to the link state retransmission list */ | 
					
						
							|  |  |  |       ospf_lsa_lsrt_up(en, n); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       used = 1; | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-05-31 18:21:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* 13.3 (2) */ | 
					
						
							|  |  |  |     if (!used) | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2000-05-31 18:21:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     if (from && (from->ifa == ifa)) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* 13.3 (3) */ | 
					
						
							|  |  |  |       if ((from->rid == ifa->drid) || (from->rid == ifa->bdrid)) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* 13.3 (4) */ | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |       if (ifa->state == OSPF_IS_BACKUP) | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       back = 1; | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-04-18 22:07:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* 13.3 (5) - finally flood the packet */ | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     ospf_enqueue_lsa(p, en, ifa); | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return back; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint | 
					
						
							|  |  |  | ospf_prepare_lsupd(struct ospf_proto *p, struct ospf_iface *ifa, | 
					
						
							|  |  |  | 		   struct top_hash_entry **lsa_list, uint lsa_count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct ospf_packet *pkt; | 
					
						
							|  |  |  |   uint hlen, pos, i, maxsize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pkt = ospf_tx_buffer(ifa); | 
					
						
							|  |  |  |   hlen = ospf_lsupd_hdrlen(p); | 
					
						
							|  |  |  |   maxsize = ospf_pkt_maxsize(ifa); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ospf_pkt_fill_hdr(ifa, pkt, LSUPD_P); | 
					
						
							|  |  |  |   pos = hlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; i < lsa_count; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     struct top_hash_entry *en = lsa_list[i]; | 
					
						
							|  |  |  |     uint len = en->lsa.length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((pos + len) > maxsize) | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* The packet if full, stop adding LSAs and sent it */ | 
					
						
							|  |  |  |       if (i > 0) | 
					
						
							|  |  |  | 	break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* LSA is larger than MTU, check buffer size */ | 
					
						
							|  |  |  |       if (ospf_iface_assure_bufsize(ifa, pos + len) < 0) | 
					
						
							| 
									
										
										
										
											2013-11-22 18:45:57 +01:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	/* Cannot fit in a tx buffer, skip that */ | 
					
						
							| 
									
										
										
										
											2014-07-19 17:28:38 +02:00
										 |  |  | 	log(L_ERR "%s: LSA too large to send on %s (Type: %04x, Id: %R, Rt: %R)", | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	    p->p.name, ifa->ifname, en->lsa_type, en->lsa.id, en->lsa.rt); | 
					
						
							|  |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2013-11-22 18:45:57 +01:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* TX buffer could be reallocated */ | 
					
						
							|  |  |  |       pkt = ospf_tx_buffer(ifa); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-02-06 17:46:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     struct ospf_lsa_header *buf = ((void *) pkt) + pos; | 
					
						
							|  |  |  |     lsa_hton_hdr(&en->lsa, buf); | 
					
						
							|  |  |  |     lsa_hton_body(en->lsa_body, ((void *) buf) + sizeof(struct ospf_lsa_header), | 
					
						
							|  |  |  | 		  len - sizeof(struct ospf_lsa_header)); | 
					
						
							|  |  |  |     buf->age = htons(MIN(en->lsa.age + ifa->inftransdelay, LSA_MAXAGE)); | 
					
						
							| 
									
										
										
										
											2014-02-06 17:46:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     pos += len; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-06-04 14:03:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   ospf_lsupd_set_lsa_count(pkt, hlen, i); | 
					
						
							|  |  |  |   pkt->length = htons(pos); | 
					
						
							| 
									
										
										
										
											2000-05-02 22:31:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   return i; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 14:03:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | static int | 
					
						
							|  |  |  | ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa) | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   uint i, c; | 
					
						
							| 
									
										
										
										
											2004-06-04 14:03:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   for (i = 0; i < lsa_min_count; i += c) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i); | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     if (!c)	/* Too large LSA */ | 
					
						
							|  |  |  |       { i++; continue; } | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa), | 
					
						
							|  |  |  | 		"LSUPD packet flooded via %s", ifa->ifname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ifa->type == OSPF_IT_BCAST) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) | 
					
						
							|  |  |  | 	ospf_send_to_all(ifa); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	ospf_send_to_des(ifa); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |       ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE); | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return i; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-12-24 18:08:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | int | 
					
						
							|  |  |  | ospf_send_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, struct ospf_neighbor *n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct ospf_iface *ifa = n->ifa; | 
					
						
							|  |  |  |   uint i, c; | 
					
						
							| 
									
										
										
										
											2004-07-14 21:46:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   for (i = 0; i < lsa_count; i += c) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i); | 
					
						
							| 
									
										
										
										
											2010-12-24 18:08:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     if (!c)	/* Too large LSA */ | 
					
						
							|  |  |  |       { i++; continue; } | 
					
						
							| 
									
										
										
										
											2010-12-24 18:08:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa), | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  | 		"LSUPD packet sent to nbr %R on %s", n->rid, ifa->ifname); | 
					
						
							| 
									
										
										
										
											2004-07-14 21:46:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     ospf_send_to(ifa, n->ip); | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   return i; | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | void | 
					
						
							|  |  |  | ospf_rxmt_lsupd(struct ospf_proto *p, struct ospf_neighbor *n) | 
					
						
							| 
									
										
										
										
											2000-03-31 00:21:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   uint max = 2 * n->ifa->flood_queue_size; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   struct top_hash_entry *entries[max]; | 
					
						
							|  |  |  |   struct top_hash_entry *ret, *nxt, *en; | 
					
						
							|  |  |  |   uint i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   /* ASSERT((n->state >= NEIGHBOR_EXCHANGE) && !EMPTY_SLIST(n->lsrtl)); */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   WALK_SLIST_DELSAFE(ret, nxt, n->lsrtl) | 
					
						
							| 
									
										
										
										
											2000-03-31 00:21:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     if (i == max) | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2010-11-04 17:22:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     en = ospf_hash_find_entry(p->gr, ret); | 
					
						
							|  |  |  |     if (!en) | 
					
						
							| 
									
										
										
										
											2000-03-31 00:21:41 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* Probably flushed LSA, this should not happen */ | 
					
						
							|  |  |  |       log(L_WARN "%s: LSA disappeared (Type: %04x, Id: %R, Rt: %R)", | 
					
						
							|  |  |  | 	  p->p.name, ret->lsa_type, ret->lsa.id, ret->lsa.rt); | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       s_rem_node(SNODE ret); | 
					
						
							|  |  |  |       ospf_hash_delete(n->lsrth, ret); | 
					
						
							| 
									
										
										
										
											2000-03-31 00:21:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-02-06 17:46:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     entries[i] = en; | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-11-04 17:22:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   ospf_send_lsupd(p, entries, i, n); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2000-03-31 01:14:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-04 17:22:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | static inline int | 
					
						
							|  |  |  | ospf_addr_is_local(struct ospf_proto *p, struct ospf_area *oa, ip_addr ip) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct ospf_iface *ifa; | 
					
						
							|  |  |  |   WALK_LIST(ifa, p->iface_list) | 
					
						
							|  |  |  |     if ((ifa->oa == oa) && ifa->addr && ipa_equal(ifa->addr->ip, ip)) | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2000-03-31 00:21:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-30 20:00:42 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa, | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 		   struct ospf_neighbor *n) | 
					
						
							| 
									
										
										
										
											2000-03-30 20:00:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   struct ospf_proto *p = ifa->oa->po; | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |   const char *err_dsc = NULL; | 
					
						
							|  |  |  |   uint plen, err_val = 0; | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |   /* RFC 2328 13. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   plen = ntohs(pkt->length); | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   if (plen < ospf_lsupd_hdrlen(p)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)", n->rid, ifa->ifname, "too short", plen); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |   OSPF_PACKET(ospf_dump_lsupd, pkt, "LSUPD packet received from nbr %R on %s", n->rid, ifa->ifname); | 
					
						
							| 
									
										
										
										
											2009-10-29 23:57:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (n->state < NEIGHBOR_EXCHANGE) | 
					
						
							| 
									
										
										
										
											2000-05-11 22:00:55 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |     OSPF_TRACE(D_PACKETS, "LSUPD packet ignored - lesser state than Exchange"); | 
					
						
							| 
									
										
										
										
											2000-05-11 22:00:55 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-04-02 20:41:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  |   ospf_neigh_sm(n, INM_HELLOREC);	/* Questionable */ | 
					
						
							| 
									
										
										
										
											2000-05-09 18:17:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   uint offset, i, lsa_count; | 
					
						
							|  |  |  |   ospf_lsupd_body(p, pkt, &offset, &lsa_count); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |   for (i = 0; i < lsa_count; i++) | 
					
						
							| 
									
										
										
										
											2000-04-02 20:41:33 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     struct ospf_lsa_header lsa, *lsa_n; | 
					
						
							|  |  |  |     struct top_hash_entry *en; | 
					
						
							|  |  |  |     u32 lsa_len, lsa_type, lsa_domain; | 
					
						
							| 
									
										
										
										
											2000-05-10 15:04:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     if ((offset + sizeof(struct ospf_lsa_header)) > plen) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       DROP("too short", plen); | 
					
						
							| 
									
										
										
										
											2000-05-10 15:04:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* LSA header in network order */ | 
					
						
							|  |  |  |     lsa_n = ((void *) pkt) + offset; | 
					
						
							|  |  |  |     lsa_len = ntohs(lsa_n->length); | 
					
						
							|  |  |  |     offset += lsa_len; | 
					
						
							| 
									
										
										
										
											2014-07-19 17:28:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |     if (offset > plen) | 
					
						
							|  |  |  |       DROP("too short", plen); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |     if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header))) | 
					
						
							|  |  |  |       DROP("invalid LSA length", lsa_len); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* LSA header in host order */ | 
					
						
							|  |  |  |     lsa_ntoh_hdr(lsa_n, &lsa); | 
					
						
							|  |  |  |     lsa_get_type_domain(&lsa, ifa, &lsa_type, &lsa_domain); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DBG("Update Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n", | 
					
						
							|  |  |  | 	lsa_type, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-01 14:40:56 +02:00
										 |  |  |     /* RFC 2328 13. (1) - verify LSA checksum */ | 
					
						
							|  |  |  |     if ((lsa_n->checksum == 0) || !lsa_verify_checksum(lsa_n, lsa_len)) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       SKIP("invalid checksum"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* RFC 2328 13. (2) */ | 
					
						
							|  |  |  |     if (!lsa_type) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       SKIP("unknown type"); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* RFC 5340 4.5.1 (2) and RFC 2328 13. (3) */ | 
					
						
							|  |  |  |     if (!oa_is_ext(ifa->oa) && (LSA_SCOPE(lsa_type) == LSA_SCOPE_AS)) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       SKIP("AS scope in stub area"); | 
					
						
							| 
									
										
										
										
											2012-08-06 11:09:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* Errata 3746 to RFC 2328 - rt-summary-LSAs forbidden in stub areas */ | 
					
						
							|  |  |  |     if (!oa_is_ext(ifa->oa) && (lsa_type == LSA_T_SUM_RT)) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       SKIP("rt-summary-LSA in stub area"); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* RFC 5340 4.5.1 (3) */ | 
					
						
							|  |  |  |     if (LSA_SCOPE(lsa_type) == LSA_SCOPE_RES) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       SKIP("invalid scope"); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* Find local copy of LSA in link state database */ | 
					
						
							|  |  |  |     en = ospf_hash_find(p->gr, lsa_domain, lsa.id, lsa.rt, lsa_type); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef LOCAL_DEBUG
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     if (en) | 
					
						
							|  |  |  |       DBG("I have Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n", | 
					
						
							|  |  |  | 	  en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age, en->lsa.checksum); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-04-04 15:55:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* 13. (4) - ignore maxage LSA if i have no local copy */ | 
					
						
							|  |  |  |     if ((lsa.age == LSA_MAXAGE) && !en && (p->padj == 0)) | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-07-19 17:28:38 +02:00
										 |  |  |       /* 13.5. - schedule ACKs (tbl 19, case 5) */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* 13. (5) - received LSA is newer (or no local copy) */ | 
					
						
							|  |  |  |     if (!en || (lsa_comp(&lsa, &en->lsa) == CMP_NEWER)) | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* 13. (5a) - enforce minimum time between updates for received LSAs */ | 
					
						
							|  |  |  |       /* We also use this to ratelimit reactions to received self-originated LSAs */ | 
					
						
							|  |  |  |       if (en && ((now - en->inst_time) < MINLSARRIVAL)) | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	OSPF_TRACE(D_EVENTS, "Skipping LSA received in less that MinLSArrival"); | 
					
						
							|  |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* Copy and validate LSA body */ | 
					
						
							|  |  |  |       int blen = lsa.length - sizeof(struct ospf_lsa_header); | 
					
						
							|  |  |  |       void *body = mb_alloc(p->p.pool, blen); | 
					
						
							|  |  |  |       lsa_ntoh_body(lsa_n + 1, body, blen); | 
					
						
							| 
									
										
										
										
											2009-12-12 01:35:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (lsa_validate(&lsa, lsa_type, ospf_is_v2(p), body) == 0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	mb_free(body); | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  | 	SKIP("invalid body"); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2000-05-09 21:06:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* 13. (5f) - handle self-originated LSAs, see also 13.4. */ | 
					
						
							|  |  |  |       if ((lsa.rt == p->router_id) || | 
					
						
							|  |  |  | 	  (ospf_is_v2(p) && (lsa_type == LSA_T_NET) && ospf_addr_is_local(p, ifa->oa, ipa_from_u32(lsa.id)))) | 
					
						
							| 
									
										
										
										
											2000-04-18 22:11:05 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	OSPF_TRACE(D_EVENTS, "Received unexpected self-originated LSA"); | 
					
						
							|  |  |  | 	ospf_advance_lsa(p, en, &lsa, lsa_type, lsa_domain, body); | 
					
						
							| 
									
										
										
										
											2000-04-18 22:11:05 +00:00
										 |  |  | 	continue; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-04 21:05:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |       /* 13. (5c) - remove old LSA from all retransmission lists
 | 
					
						
							|  |  |  |        * | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |        * We only need to remove it from the retransmission list of the neighbor | 
					
						
							|  |  |  |        * that send us the new LSA. The old LSA is automatically replaced in | 
					
						
							|  |  |  |        * retransmission lists by the new LSA. | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (en) | 
					
						
							|  |  |  | 	ospf_lsa_lsrt_down(en, n); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /*
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |        * Old code for removing LSA from all retransmission lists. Must be done | 
					
						
							|  |  |  |        * before (5b), otherwise it also removes the new entries from (5b). | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       struct ospf_iface *ifi; | 
					
						
							|  |  |  |       struct ospf_neighbor *ni; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       WALK_LIST(ifi, p->iface_list) | 
					
						
							|  |  |  | 	WALK_LIST(ni, ifi->neigh_list) | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  | 	  if (ni->state > NEIGHBOR_EXSTART) | 
					
						
							|  |  |  | 	    ospf_lsa_lsrt_down(en, ni); | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-05-07 15:54:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* 13. (5d) - install new LSA into database */ | 
					
						
							|  |  |  |       en = ospf_install_lsa(p, &lsa, lsa_type, lsa_domain, body); | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* RFC 5340 4.4.3 Events 6+7 - new Link LSA received */ | 
					
						
							|  |  |  |       if (lsa_type == LSA_T_LINK) | 
					
						
							|  |  |  | 	ospf_notify_net_lsa(ifa); | 
					
						
							| 
									
										
										
										
											2009-10-29 23:57:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* 13. (5b) - flood new LSA */ | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |       int flood_back = ospf_flood_lsa(p, en, n); | 
					
						
							| 
									
										
										
										
											2009-10-29 23:57:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-19 17:28:38 +02:00
										 |  |  |       /* 13.5. - schedule ACKs (tbl 19, cases 1+2) */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (! flood_back) | 
					
						
							|  |  |  | 	if ((ifa->state != OSPF_IS_BACKUP) || (n->rid == ifa->drid)) | 
					
						
							|  |  |  | 	  ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY); | 
					
						
							| 
									
										
										
										
											2000-04-04 15:55:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* FIXME: remove LSA entry if it is LSA_MAXAGE and it is possible? */ | 
					
						
							| 
									
										
										
										
											2009-09-08 13:45:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     /* 13. (6) - received LSA is in Link state request list (but not newer) */ | 
					
						
							|  |  |  |     if (ospf_hash_find_entry(n->lsrqh, en) != NULL) | 
					
						
							|  |  |  |       DROP1("error in LSA database exchange"); | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* 13. (7) - received LSA is same */ | 
					
						
							|  |  |  |     if (lsa_comp(&lsa, &en->lsa) == CMP_SAME) | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* Duplicate LSA, treat as implicit ACK */ | 
					
						
							|  |  |  |       int implicit_ack = ospf_lsa_lsrt_down(en, n); | 
					
						
							| 
									
										
										
										
											2010-05-07 15:54:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-19 17:28:38 +02:00
										 |  |  |       /* 13.5. - schedule ACKs (tbl 19, cases 3+4) */ | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       if (implicit_ack) | 
					
						
							| 
									
										
										
										
											2000-04-18 21:40:11 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  | 	if ((ifa->state == OSPF_IS_BACKUP) && (n->rid == ifa->drid)) | 
					
						
							|  |  |  | 	  ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY); | 
					
						
							| 
									
										
										
										
											2000-04-18 21:40:11 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       else | 
					
						
							|  |  |  | 	ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-18 21:40:11 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     /* 13. (8) - received LSA is older */ | 
					
						
							| 
									
										
										
										
											2000-04-18 01:06:16 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* Seqnum is wrapping, wait until it is flushed */ | 
					
						
							|  |  |  |       if ((en->lsa.age == LSA_MAXAGE) && (en->lsa.sn == LSA_MAXSEQNO)) | 
					
						
							|  |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2000-04-04 00:32:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |       /* Send newer local copy back to neighbor */ | 
					
						
							|  |  |  |       /* FIXME - check for MinLSArrival ? */ | 
					
						
							|  |  |  |       ospf_send_lsupd(p, &en, 1, n); | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2000-04-05 00:51:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   skip: | 
					
						
							|  |  |  |     LOG_LSA1("Bad LSA (Type: %04x, Id: %R, Rt: %R) in LSUPD", lsa_type, lsa.id, lsa.rt); | 
					
						
							|  |  |  |     LOG_LSA2("  received from nbr %R on %s - %s", n->rid, ifa->ifname, err_dsc); | 
					
						
							| 
									
										
										
										
											2000-04-02 20:41:33 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |   /* Send direct LSACKs */ | 
					
						
							|  |  |  |   ospf_send_lsack(p, n, ACKL_DIRECT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   /* Send enqueued LSAs immediately, do not wait for flood_event */ | 
					
						
							|  |  |  |   if (ev_active(p->flood_event)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ev_postpone(p->flood_event); | 
					
						
							|  |  |  |     ospf_flood_event(p); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |   /*
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |    * During loading, we should ask for another batch of LSAs. This is only | 
					
						
							|  |  |  |    * vaguely mentioned in RFC 2328. We send a new LSREQ if all requests sent in | 
					
						
							|  |  |  |    * the last packet were already answered and/or removed from the LS request | 
					
						
							|  |  |  |    * list and therefore lsrqi is pointing to the first node of the list. | 
					
						
							| 
									
										
										
										
											2014-07-18 18:24:12 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   if (!EMPTY_SLIST(n->lsrql) && (n->lsrqi == SHEAD(n->lsrql))) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2014-06-26 11:58:57 +02:00
										 |  |  |     ospf_send_lsreq(p, n); | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |     tm_start(n->lsrq_timer, n->ifa->rxmtint); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | drop: | 
					
						
							|  |  |  |   LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)", | 
					
						
							|  |  |  | 	  n->rid, ifa->ifname, err_dsc, err_val); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 10:42:55 +01:00
										 |  |  |   /* Malformed LSUPD - there is no defined error event, we abuse BadLSReq */ | 
					
						
							|  |  |  |   ospf_neigh_sm(n, INM_BADLSREQ); | 
					
						
							| 
									
										
										
										
											2014-10-24 10:27:21 +02:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2000-03-30 20:00:42 +00:00
										 |  |  | } |