| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *	BIRD -- OSPF | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-07-01 15:01:04 +00:00
										 |  |  |  *	(c) 1999--2004 Ondrej Filip <feela@network.cz> | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *	Can be freely distributed and used under the terms of the GNU GPL. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ospf.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef OSPFv2
 | 
					
						
							|  |  |  | struct ospf_hello_packet | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct ospf_packet ospf_packet; | 
					
						
							|  |  |  |   ip_addr netmask; | 
					
						
							|  |  |  |   u16 helloint; | 
					
						
							|  |  |  |   u8 options; | 
					
						
							|  |  |  |   u8 priority; | 
					
						
							|  |  |  |   u32 deadint; | 
					
						
							|  |  |  |   u32 dr; | 
					
						
							|  |  |  |   u32 bdr; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef OSPFv3
 | 
					
						
							|  |  |  | struct ospf_hello_packet | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct ospf_packet ospf_packet; | 
					
						
							|  |  |  |   u32 iface_id; | 
					
						
							|  |  |  |   u8 priority; | 
					
						
							|  |  |  |   u8 options3; | 
					
						
							|  |  |  |   u8 options2; | 
					
						
							|  |  |  |   u8 options; | 
					
						
							|  |  |  |   u16 helloint; | 
					
						
							|  |  |  |   u16 deadint; | 
					
						
							|  |  |  |   u32 dr; | 
					
						
							|  |  |  |   u32 bdr; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, | 
					
						
							|  |  |  | 		   struct ospf_neighbor *n, ip_addr faddr) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |   struct proto_ospf *po = ifa->oa->po; | 
					
						
							|  |  |  |   struct proto *p = &po->proto; | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |   char *beg = "OSPF: Bad HELLO packet from "; | 
					
						
							| 
									
										
										
										
											2010-02-21 14:34:53 +01:00
										 |  |  |   unsigned int size, i, twoway, eligible, peers; | 
					
						
							|  |  |  |   u32 tmp; | 
					
						
							| 
									
										
										
										
											2009-10-29 23:57:42 +01:00
										 |  |  |   u32 *pnrid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   size = ntohs(ps_i->length); | 
					
						
							|  |  |  |   if (size < sizeof(struct ospf_hello_packet)) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |     log(L_ERR "%s%I - too short (%u B)", beg, faddr, size); | 
					
						
							| 
									
										
										
										
											2009-10-29 23:57:42 +01:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct ospf_hello_packet *ps = (void *) ps_i; | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  |   OSPF_TRACE(D_PACKETS, "HELLO packet received from %I via %s%s", faddr, | 
					
						
							| 
									
										
										
										
											2004-07-14 21:46:20 +00:00
										 |  |  |       (ifa->type == OSPF_IT_VLINK ? "vlink-" : ""), ifa->iface->name); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef OSPFv2
 | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |   ip_addr mask = ps->netmask; | 
					
						
							| 
									
										
										
										
											2000-06-08 02:28:04 +00:00
										 |  |  |   ipa_ntoh(mask); | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |   if ((ifa->type != OSPF_IT_VLINK) && | 
					
						
							|  |  |  |       (ifa->type != OSPF_IT_PTP) && | 
					
						
							|  |  |  |       !ipa_equal(mask, ipa_mkmask(ifa->addr->pxlen))) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     log(L_ERR "%s%I - netmask mismatch (%I)", beg, faddr, mask); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |   tmp = ntohs(ps->helloint); | 
					
						
							|  |  |  |   if (tmp != ifa->helloint) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |     log(L_ERR "%s%I - hello interval mismatch (%d)", beg, faddr, tmp); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv2
 | 
					
						
							|  |  |  |   tmp = ntohl(ps->deadint); | 
					
						
							|  |  |  | #else /* OSPFv3 */
 | 
					
						
							|  |  |  |   tmp = ntohs(ps->deadint); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   if (tmp != ifa->dead) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |     log(L_ERR "%s%I - dead interval mismatch (%d)", beg, faddr, tmp); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |   tmp = !(ps->options & OPT_E); | 
					
						
							| 
									
										
										
										
											2010-05-02 19:58:34 +02:00
										 |  |  |   if (tmp != !!ifa->oa->stub) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |     log(L_ERR "%s%I - stub area flag mismatch (%d)", beg, faddr, tmp); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-06 19:53:52 +00:00
										 |  |  |   if (!n) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |     if ((ifa->type == OSPF_IT_NBMA)) | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       struct nbma_node *nn; | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |       int found = 0; | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |       WALK_LIST(nn, ifa->nbma_list) | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2004-07-13 23:42:14 +00:00
										 |  |  | 	if (ipa_equal(faddr, nn->ip)) | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 	  found = 1; | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | 	  break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |       if ((found == 0) && (ifa->strictnbma)) | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  | 	log(L_WARN "Ignoring new neighbor: %I on %s", faddr, | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 	    ifa->iface->name); | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |       if (found) | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 	eligible = nn->eligible; | 
					
						
							|  |  |  | 	if (((ps->priority == 0) && eligible) | 
					
						
							|  |  |  | 	    || ((ps->priority > 0) && (eligible == 0))) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  log(L_ERR "Eligibility mismatch for neighbor: %I on %s", | 
					
						
							|  |  |  | 	      faddr, ifa->iface->name); | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | 	  return; | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |     OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr, | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 	       ifa->iface->name); | 
					
						
							| 
									
										
										
										
											2004-06-04 12:53:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     n = ospf_neighbor_new(ifa); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-06 19:53:52 +00:00
										 |  |  |     n->rid = ntohl(((struct ospf_packet *) ps)->routerid); | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |     n->ip = faddr; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |     n->dr = ntohl(ps->dr); | 
					
						
							|  |  |  |     n->bdr = ntohl(ps->bdr); | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |     n->priority = ps->priority; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv3
 | 
					
						
							|  |  |  |     n->iface_id = ntohl(ps->iface_id); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   ospf_neigh_sm(n, INM_HELLOREC); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   pnrid = (u32 *) ((struct ospf_hello_packet *) (ps + 1)); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-01 15:01:04 +00:00
										 |  |  |   peers = (size - sizeof(struct ospf_hello_packet))/ sizeof(u32); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   twoway = 0; | 
					
						
							| 
									
										
										
										
											2004-07-01 15:01:04 +00:00
										 |  |  |   for (i = 0; i < peers; i++) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     if (ntohl(pnrid[i]) == po->router_id) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2000-05-10 23:42:13 +00:00
										 |  |  |       DBG("%s: Twoway received from %I\n", p->name, faddr); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |       ospf_neigh_sm(n, INM_2WAYREC); | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |       twoway = 1; | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   if (!twoway) | 
					
						
							|  |  |  |     ospf_neigh_sm(n, INM_1WAYREC); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:34:53 +01:00
										 |  |  |   u32 olddr = n->dr; | 
					
						
							|  |  |  |   u32 oldbdr = n->bdr; | 
					
						
							|  |  |  |   u32 oldpriority = n->priority; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv3
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:34:53 +01:00
										 |  |  |   u32 oldiface_id = n->iface_id; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   n->dr = ntohl(ps->dr); | 
					
						
							|  |  |  |   n->bdr = ntohl(ps->bdr); | 
					
						
							| 
									
										
										
										
											2000-05-09 11:27:31 +00:00
										 |  |  |   n->priority = ps->priority; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv3
 | 
					
						
							|  |  |  |   n->iface_id = ntohl(ps->iface_id); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-09 11:27:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   /* Check priority change */ | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   if (n->state >= NEIGHBOR_2WAY) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv2
 | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     u32 neigh = ipa_to_u32(n->ip); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #else /* OSPFv3 */
 | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     u32 neigh = n->rid; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |     if (n->priority != oldpriority) | 
					
						
							| 
									
										
										
										
											2004-06-06 08:12:42 +00:00
										 |  |  |       ospf_iface_sm(ifa, ISM_NEICH); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv3
 | 
					
						
							|  |  |  |     if (n->iface_id != oldiface_id) | 
					
						
							|  |  |  |       ospf_iface_sm(ifa, ISM_NEICH); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     /* Neighbor is declaring itself ad DR and there is no BDR */ | 
					
						
							|  |  |  |     if ((n->dr == neigh) && (n->bdr == 0) | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  | 	&& (n->state != NEIGHBOR_FULL)) | 
					
						
							| 
									
										
										
										
											2004-06-06 08:12:42 +00:00
										 |  |  |       ospf_iface_sm(ifa, ISM_BACKS); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-09 11:27:31 +00:00
										 |  |  |     /* Neighbor is declaring itself as BDR */ | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     if ((n->bdr == neigh) && (n->state != NEIGHBOR_FULL)) | 
					
						
							| 
									
										
										
										
											2004-06-06 08:12:42 +00:00
										 |  |  |       ospf_iface_sm(ifa, ISM_BACKS); | 
					
						
							| 
									
										
										
										
											2000-05-09 11:27:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Neighbor is newly declaring itself as DR or BDR */ | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     if (((n->dr == neigh) && (n->dr != olddr)) | 
					
						
							|  |  |  | 	|| ((n->bdr == neigh) && (n->bdr != oldbdr))) | 
					
						
							| 
									
										
										
										
											2004-06-06 08:12:42 +00:00
										 |  |  |       ospf_iface_sm(ifa, ISM_NEICH); | 
					
						
							| 
									
										
										
										
											2000-05-09 11:27:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Neighbor is no more declaring itself as DR or BDR */ | 
					
						
							| 
									
										
										
										
											2009-12-11 01:20:53 +01:00
										 |  |  |     if (((olddr == neigh) && (n->dr != olddr)) | 
					
						
							|  |  |  | 	|| ((oldbdr == neigh) && (n->bdr != oldbdr))) | 
					
						
							| 
									
										
										
										
											2004-06-06 08:12:42 +00:00
										 |  |  |       ospf_iface_sm(ifa, ISM_NEICH); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-14 21:46:20 +00:00
										 |  |  |   if (ifa->type == OSPF_IT_NBMA) | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |     if ((ifa->priority == 0) && (n->priority > 0)) | 
					
						
							|  |  |  |       ospf_hello_send(NULL, 0, n); | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   ospf_neigh_sm(n, INM_HELLOREC); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   struct ospf_iface *ifa; | 
					
						
							|  |  |  |   struct ospf_hello_packet *pkt; | 
					
						
							|  |  |  |   struct ospf_packet *op; | 
					
						
							|  |  |  |   struct proto *p; | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |   struct ospf_neighbor *neigh, *n1; | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  |   u16 length; | 
					
						
							|  |  |  |   u32 *pp; | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |   int i, send; | 
					
						
							|  |  |  |   struct nbma_node *nb; | 
					
						
							| 
									
										
										
										
											2004-07-15 16:37:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   if (timer == NULL) | 
					
						
							|  |  |  |     ifa = dirn->ifa; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     ifa = (struct ospf_iface *) timer->data; | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |   if (ifa->state == OSPF_IS_DOWN) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   if (ifa->stub) | 
					
						
							|  |  |  |     return;			/* Don't send any packet on stub iface */ | 
					
						
							| 
									
										
										
										
											2000-09-02 08:54:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-15 16:37:52 +00:00
										 |  |  |   p = (struct proto *) (ifa->oa->po); | 
					
						
							| 
									
										
										
										
											2010-03-14 16:36:59 +01:00
										 |  |  |   DBG("%s: Hello/Poll timer fired on interface %s with IP %I\n", | 
					
						
							|  |  |  |       p->name, ifa->iface->name, ifa->addr->ip); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |   /* Now we should send a hello packet */ | 
					
						
							| 
									
										
										
										
											2010-03-11 18:07:24 +01:00
										 |  |  |   pkt = ospf_tx_buffer(ifa); | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |   op = &pkt->ospf_packet; | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |   /* Now fill ospf_hello header */ | 
					
						
							| 
									
										
										
										
											2004-06-26 20:15:34 +00:00
										 |  |  |   ospf_pkt_fill_hdr(ifa, pkt, HELLO_P); | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #ifdef OSPFv2
 | 
					
						
							| 
									
										
										
										
											2010-02-11 10:23:35 +01:00
										 |  |  |   pkt->netmask = ipa_mkmask(ifa->addr->pxlen); | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |   ipa_hton(pkt->netmask); | 
					
						
							| 
									
										
										
										
											2009-05-24 17:55:33 +02:00
										 |  |  |   if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP)) | 
					
						
							|  |  |  |     pkt->netmask = IPA_NONE; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   pkt->helloint = ntohs(ifa->helloint); | 
					
						
							|  |  |  |   pkt->priority = ifa->priority; | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef OSPFv3
 | 
					
						
							|  |  |  |   pkt->iface_id = htonl(ifa->iface->index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pkt->options3 = ifa->oa->options >> 16; | 
					
						
							|  |  |  |   pkt->options2 = ifa->oa->options >> 8; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   pkt->options = ifa->oa->options; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef OSPFv2
 | 
					
						
							| 
									
										
										
										
											2005-02-20 04:27:56 +00:00
										 |  |  |   pkt->deadint = htonl(ifa->dead); | 
					
						
							| 
									
										
										
										
											2009-08-21 09:27:52 +02:00
										 |  |  |   pkt->dr = htonl(ipa_to_u32(ifa->drip)); | 
					
						
							|  |  |  |   pkt->bdr = htonl(ipa_to_u32(ifa->bdrip)); | 
					
						
							|  |  |  | #else /* OSPFv3 */
 | 
					
						
							|  |  |  |   pkt->deadint = htons(ifa->dead); | 
					
						
							|  |  |  |   pkt->dr = htonl(ifa->drid); | 
					
						
							|  |  |  |   pkt->bdr = htonl(ifa->bdrid); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* Fill all neighbors */ | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   i = 0; | 
					
						
							|  |  |  |   pp = (u32 *) (((u8 *) pkt) + sizeof(struct ospf_hello_packet)); | 
					
						
							|  |  |  |   WALK_LIST(neigh, ifa->neigh_list) | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2004-06-26 20:15:34 +00:00
										 |  |  |     if ((i+1) * sizeof(u32) + sizeof(struct ospf_hello_packet) > ospf_pkt_maxsize(ifa)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       OSPF_TRACE(D_PACKETS, "Too many neighbors on the interface!"); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |     *(pp + i) = htonl(neigh->rid); | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |     i++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-04 17:12:27 +00:00
										 |  |  |   length = sizeof(struct ospf_hello_packet) + i * sizeof(u32); | 
					
						
							|  |  |  |   op->length = htons(length); | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |   switch(ifa->type) | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |     case OSPF_IT_NBMA: | 
					
						
							|  |  |  |       if (timer == NULL)		/* Response to received hello */ | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |         ospf_send_to(ifa, dirn->ip); | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |         int toall = 0; | 
					
						
							|  |  |  |         int meeli = 0; | 
					
						
							|  |  |  |         if (ifa->state > OSPF_IS_DROTHER) | 
					
						
							|  |  |  |           toall = 1; | 
					
						
							|  |  |  |         if (ifa->priority > 0) | 
					
						
							|  |  |  |           meeli = 1; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |         WALK_LIST(nb, ifa->nbma_list) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           send = 1; | 
					
						
							|  |  |  |           WALK_LIST(n1, ifa->neigh_list) | 
					
						
							|  |  |  |           { | 
					
						
							| 
									
										
										
										
											2004-07-13 23:42:14 +00:00
										 |  |  |             if (ipa_equal(nb->ip, n1->ip)) | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |               send = 0; | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if ((poll == 1) && (send)) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             if (toall || (meeli && nb->eligible)) | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |               ospf_send_to(ifa, nb->ip); | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (poll == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           WALK_LIST(n1, ifa->neigh_list) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             if (toall || (n1->rid == ifa->drid) || (n1->rid == ifa->bdrid) || | 
					
						
							|  |  |  |                 (meeli && (n1->priority > 0))) | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |               ospf_send_to(ifa, n1->ip); | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2000-09-02 00:03:36 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case OSPF_IT_VLINK: | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |       ospf_send_to(ifa, ifa->vip); | 
					
						
							| 
									
										
										
										
											2004-06-25 16:39:53 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2009-09-04 11:06:51 +02:00
										 |  |  |       ospf_send_to(ifa, AllSPFRouters); | 
					
						
							| 
									
										
										
										
											2000-06-05 23:44:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-06 16:17:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s%s", | 
					
						
							|  |  |  | 	     (ifa->type == OSPF_IT_VLINK ? "vlink-" : ""), ifa->iface->name); | 
					
						
							| 
									
										
										
										
											1999-11-17 15:50:41 +00:00
										 |  |  | } |