blob: 45dabc54f4bd5864662c0ab2a99aa6c3829856ed [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Sending and Receiving OSPF Packets.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "memory.h"
27#include "linklist.h"
28#include "prefix.h"
29#include "if.h"
30#include "table.h"
31#include "sockunion.h"
32#include "stream.h"
33#include "log.h"
paul2dd8bb42004-07-23 15:13:48 +000034#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000035#include "md5-gnu.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_flood.h"
49#include "ospfd/ospf_dump.h"
50
hasso52dc7ee2004-09-23 19:18:23 +000051static void ospf_ls_ack_send_list (struct ospf_interface *, struct list *,
paul718e3742002-12-13 20:15:29 +000052 struct in_addr);
53
54/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000055const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000056{
57 "unknown",
58 "Hello",
59 "Database Description",
60 "Link State Request",
61 "Link State Update",
62 "Link State Acknowledgment",
63};
64
65extern int in_cksum (void *ptr, int nbytes);
66
67/* OSPF authentication checking function */
68int
69ospf_auth_type (struct ospf_interface *oi)
70{
71 int auth_type;
72
73 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
74 auth_type = oi->area->auth_type;
75 else
76 auth_type = OSPF_IF_PARAM (oi, auth_type);
77
78 /* Handle case where MD5 key list is not configured aka Cisco */
79 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
80 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
81 return OSPF_AUTH_NULL;
82
83 return auth_type;
84
85}
86
87/* forward output pointer. */
88void
89ospf_output_forward (struct stream *s, int size)
90{
91 s->putp += size;
92}
93
94struct ospf_packet *
95ospf_packet_new (size_t size)
96{
97 struct ospf_packet *new;
98
99 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
100 new->s = stream_new (size);
101
102 return new;
103}
104
105void
106ospf_packet_free (struct ospf_packet *op)
107{
108 if (op->s)
109 stream_free (op->s);
110
111 XFREE (MTYPE_OSPF_PACKET, op);
112
113 op = NULL;
114}
115
116struct ospf_fifo *
117ospf_fifo_new ()
118{
119 struct ospf_fifo *new;
120
121 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
122 return new;
123}
124
125/* Add new packet to fifo. */
126void
127ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
128{
129 if (fifo->tail)
130 fifo->tail->next = op;
131 else
132 fifo->head = op;
133
134 fifo->tail = op;
135
136 fifo->count++;
137}
138
139/* Delete first packet from fifo. */
140struct ospf_packet *
141ospf_fifo_pop (struct ospf_fifo *fifo)
142{
143 struct ospf_packet *op;
144
145 op = fifo->head;
146
147 if (op)
148 {
149 fifo->head = op->next;
150
151 if (fifo->head == NULL)
152 fifo->tail = NULL;
153
154 fifo->count--;
155 }
156
157 return op;
158}
159
160/* Return first fifo entry. */
161struct ospf_packet *
162ospf_fifo_head (struct ospf_fifo *fifo)
163{
164 return fifo->head;
165}
166
167/* Flush ospf packet fifo. */
168void
169ospf_fifo_flush (struct ospf_fifo *fifo)
170{
171 struct ospf_packet *op;
172 struct ospf_packet *next;
173
174 for (op = fifo->head; op; op = next)
175 {
176 next = op->next;
177 ospf_packet_free (op);
178 }
179 fifo->head = fifo->tail = NULL;
180 fifo->count = 0;
181}
182
183/* Free ospf packet fifo. */
184void
185ospf_fifo_free (struct ospf_fifo *fifo)
186{
187 ospf_fifo_flush (fifo);
188
189 XFREE (MTYPE_OSPF_FIFO, fifo);
190}
191
192void
193ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
194{
ajsc3eab872005-01-29 15:52:07 +0000195 if (!oi->obuf)
196 {
197 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
198 "destination %s) called with NULL obuf, ignoring "
199 "(please report this bug)!\n",
200 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
201 ospf_packet_type_str[stream_getc_from(op->s, 1)],
202 inet_ntoa (op->dst));
203 return;
204 }
205
paul718e3742002-12-13 20:15:29 +0000206 /* Add packet to end of queue. */
207 ospf_fifo_push (oi->obuf, op);
208
209 /* Debug of packet fifo*/
210 /* ospf_fifo_debug (oi->obuf); */
211}
212
213void
214ospf_packet_delete (struct ospf_interface *oi)
215{
216 struct ospf_packet *op;
217
218 op = ospf_fifo_pop (oi->obuf);
219
220 if (op)
221 ospf_packet_free (op);
222}
223
224struct stream *
225ospf_stream_copy (struct stream *new, struct stream *s)
226{
227 new->endp = s->endp;
228 new->putp = s->putp;
229 new->getp = s->getp;
230
231 memcpy (new->data, s->data, stream_get_endp (s));
232
233 return new;
234}
235
236struct ospf_packet *
237ospf_packet_dup (struct ospf_packet *op)
238{
239 struct ospf_packet *new;
240
paul37163d62003-02-03 18:40:56 +0000241 if (stream_get_endp(op->s) != op->length)
242 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000243 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000244
245 /* Reserve space for MD5 authentication that may be added later. */
246 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000247 ospf_stream_copy (new->s, op->s);
248
249 new->dst = op->dst;
250 new->length = op->length;
251
252 return new;
253}
254
gdt86f1fd92005-01-10 14:20:43 +0000255/* XXX inline */
256unsigned int
257ospf_packet_authspace (struct ospf_interface *oi)
258{
259 int auth = 0;
260
261 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
262 auth = OSPF_AUTH_MD5_SIZE;
263
264 return auth;
265}
266
paul6c835672004-10-11 11:00:30 +0000267unsigned int
paul718e3742002-12-13 20:15:29 +0000268ospf_packet_max (struct ospf_interface *oi)
269{
270 int max;
271
gdt86f1fd92005-01-10 14:20:43 +0000272 max = oi->ifp->mtu - ospf_packet_authspace(oi);
273
paul68b73392004-09-12 14:21:37 +0000274 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000275
276 return max;
277}
278
279
280int
281ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
282 u_int16_t length)
283{
paul6c835672004-10-11 11:00:30 +0000284 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000285 struct md5_ctx ctx;
286 unsigned char digest[OSPF_AUTH_MD5_SIZE];
287 unsigned char *pdigest;
288 struct crypt_key *ck;
289 struct ospf_header *ospfh;
290 struct ospf_neighbor *nbr;
291
292
293 ibuf = STREAM_PNT (s);
294 ospfh = (struct ospf_header *) ibuf;
295
296 /* Get pointer to the end of the packet. */
297 pdigest = ibuf + length;
298
299 /* Get secret key. */
300 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
301 ospfh->u.crypt.key_id);
302 if (ck == NULL)
303 {
304 zlog_warn ("interface %s: ospf_check_md5 no key %d",
305 IF_NAME (oi), ospfh->u.crypt.key_id);
306 return 0;
307 }
308
309 /* check crypto seqnum. */
310 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
311
312 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
313 {
314 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
315 IF_NAME (oi),
316 ntohl(ospfh->u.crypt.crypt_seqnum),
317 ntohl(nbr->crypt_seqnum));
318 return 0;
319 }
320
321 /* Generate a digest for the ospf packet - their digest + our digest. */
322 md5_init_ctx (&ctx);
323 md5_process_bytes (ibuf, length, &ctx);
324 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
325 md5_finish_ctx (&ctx, digest);
326
327 /* compare the two */
328 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
329 {
330 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
331 IF_NAME (oi));
332 return 0;
333 }
334
335 /* save neighbor's crypt_seqnum */
336 if (nbr)
337 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
338 return 1;
339}
340
341/* This function is called from ospf_write(), it will detect the
342 authentication scheme and if it is MD5, it will change the sequence
343 and update the MD5 digest. */
344int
345ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
346{
347 struct ospf_header *ospfh;
348 unsigned char digest[OSPF_AUTH_MD5_SIZE];
349 struct md5_ctx ctx;
350 void *ibuf;
351 unsigned long oldputp;
paul9483e152002-12-13 20:55:25 +0000352 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000353 struct crypt_key *ck;
354 char *auth_key;
355
356 ibuf = STREAM_DATA (op->s);
357 ospfh = (struct ospf_header *) ibuf;
358
359 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
360 return 0;
361
362 /* We do this here so when we dup a packet, we don't have to
363 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000364 t = (time(NULL) & 0xFFFFFFFF);
365 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
366 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000367
368 /* Get MD5 Authentication key from auth_key list. */
369 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000370 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000371 else
372 {
373 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000374 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000375 }
376
377 /* Generate a digest for the entire packet + our secret key. */
378 md5_init_ctx (&ctx);
379 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
380 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
381 md5_finish_ctx (&ctx, digest);
382
383 /* Append md5 digest to the end of the stream. */
384 oldputp = stream_get_putp (op->s);
385 stream_set_putp (op->s, ntohs (ospfh->length));
386 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
387 stream_set_putp (op->s, oldputp);
388
389 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000390 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
391
paul37163d62003-02-03 18:40:56 +0000392 if (stream_get_endp(op->s) != op->length)
393 zlog_warn("ospf_make_md5_digest: length mismatch stream %ld ospf_packet %d", stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000394
395 return OSPF_AUTH_MD5_SIZE;
396}
397
398
399int
400ospf_ls_req_timer (struct thread *thread)
401{
402 struct ospf_neighbor *nbr;
403
404 nbr = THREAD_ARG (thread);
405 nbr->t_ls_req = NULL;
406
407 /* Send Link State Request. */
408 if (ospf_ls_request_count (nbr))
409 ospf_ls_req_send (nbr);
410
411 /* Set Link State Request retransmission timer. */
412 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
413
414 return 0;
415}
416
417void
418ospf_ls_req_event (struct ospf_neighbor *nbr)
419{
420 if (nbr->t_ls_req)
421 {
422 thread_cancel (nbr->t_ls_req);
423 nbr->t_ls_req = NULL;
424 }
425 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
426}
427
428/* Cyclic timer function. Fist registered in ospf_nbr_new () in
429 ospf_neighbor.c */
430int
431ospf_ls_upd_timer (struct thread *thread)
432{
433 struct ospf_neighbor *nbr;
434
435 nbr = THREAD_ARG (thread);
436 nbr->t_ls_upd = NULL;
437
438 /* Send Link State Update. */
439 if (ospf_ls_retransmit_count (nbr) > 0)
440 {
hasso52dc7ee2004-09-23 19:18:23 +0000441 struct list *update;
paul718e3742002-12-13 20:15:29 +0000442 struct ospf_lsdb *lsdb;
443 int i;
444 struct timeval now;
445 int retransmit_interval;
446
447 gettimeofday (&now, NULL);
448 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
449
450 lsdb = &nbr->ls_rxmt;
451 update = list_new ();
452
453 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
454 {
455 struct route_table *table = lsdb->type[i].db;
456 struct route_node *rn;
457
458 for (rn = route_top (table); rn; rn = route_next (rn))
459 {
460 struct ospf_lsa *lsa;
461
462 if ((lsa = rn->info) != NULL)
463 /* Don't retransmit an LSA if we received it within
464 the last RxmtInterval seconds - this is to allow the
465 neighbour a chance to acknowledge the LSA as it may
466 have ben just received before the retransmit timer
467 fired. This is a small tweak to what is in the RFC,
468 but it will cut out out a lot of retransmit traffic
469 - MAG */
470 if (tv_cmp (tv_sub (now, lsa->tv_recv),
471 int2tv (retransmit_interval)) >= 0)
472 listnode_add (update, rn->info);
473 }
474 }
475
476 if (listcount (update) > 0)
477 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
478 list_delete (update);
479 }
480
481 /* Set LS Update retransmission timer. */
482 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
483
484 return 0;
485}
486
487int
488ospf_ls_ack_timer (struct thread *thread)
489{
490 struct ospf_interface *oi;
491
492 oi = THREAD_ARG (thread);
493 oi->t_ls_ack = NULL;
494
495 /* Send Link State Acknowledgment. */
496 if (listcount (oi->ls_ack) > 0)
497 ospf_ls_ack_send_delayed (oi);
498
499 /* Set LS Ack timer. */
500 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
501
502 return 0;
503}
504
paul0bfeca32004-09-24 08:07:54 +0000505#ifdef WANT_OSPF_WRITE_FRAGMENT
506void
paul6a99f832004-09-27 12:56:30 +0000507ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000508 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000509 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000510{
511#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000512 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000513 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000514 int ret;
paul0bfeca32004-09-24 08:07:54 +0000515
516 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000517 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000518
519 /* we can but try.
520 *
521 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
522 * well as the IP_MF flag, making this all quite pointless.
523 *
524 * However, for a system on which IP_MF is left alone, and ip_id left
525 * alone or else which sets same ip_id for each fragment this might
526 * work, eg linux.
527 *
528 * XXX-TODO: It would be much nicer to have the kernel's use their
529 * existing fragmentation support to do this for us. Bugs/RFEs need to
530 * be raised against the various kernels.
531 */
532
533 /* set More Frag */
534 iph->ip_off |= IP_MF;
535
536 /* ip frag offset is expressed in units of 8byte words */
537 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
538
paul62d8e962004-11-02 20:26:45 +0000539 iovp = &msg->msg_iov[1];
540
paul0bfeca32004-09-24 08:07:54 +0000541 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
542 > maxdatasize )
543 {
544 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000545 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
546 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000547 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000548
paul18b12c32004-10-05 14:38:29 +0000549 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000550
paul6a99f832004-09-27 12:56:30 +0000551 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000552
paul18b12c32004-10-05 14:38:29 +0000553 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000554
555 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000556 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000557 " id %d, off %d, len %d failed with %s",
558 inet_ntoa (iph->ip_dst),
559 iph->ip_id,
560 iph->ip_off,
561 iph->ip_len,
ajs6099b3b2004-11-20 02:06:59 +0000562 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000563
paul37ccfa32004-10-31 11:24:51 +0000564 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
565 {
ajs2a42e282004-12-08 18:43:03 +0000566 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000567 iph->ip_id, iph->ip_off, iph->ip_len,
568 inet_ntoa (iph->ip_dst));
569 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
570 {
ajs2a42e282004-12-08 18:43:03 +0000571 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000572 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000573 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000574 }
575 }
576
paul0bfeca32004-09-24 08:07:54 +0000577 iph->ip_off += offset;
paul62d8e962004-11-02 20:26:45 +0000578 stream_forward (op->s, iovp->iov_len);
579 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000580 }
581
582 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000583 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
584 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000585 iph->ip_off &= (~IP_MF);
586}
587#endif /* WANT_OSPF_WRITE_FRAGMENT */
588
paul718e3742002-12-13 20:15:29 +0000589int
590ospf_write (struct thread *thread)
591{
paul68980082003-03-25 05:07:42 +0000592 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000593 struct ospf_interface *oi;
594 struct ospf_packet *op;
595 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000596 struct ip iph;
597 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000598 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000599 u_char type;
600 int ret;
601 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000602 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000603#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000604 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000605#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000606 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000607#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000608
paul68980082003-03-25 05:07:42 +0000609 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000610
paul68980082003-03-25 05:07:42 +0000611 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000612 assert (node);
613 oi = getdata (node);
614 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000615
616#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000617 /* seed ipid static with low order bits of time */
618 if (ipid == 0)
619 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000620#endif /* WANT_OSPF_WRITE_FRAGMENT */
621
paul68b73392004-09-12 14:21:37 +0000622 /* convenience - max OSPF data per packet */
623 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
624
paul718e3742002-12-13 20:15:29 +0000625 /* Get one packet from queue. */
626 op = ospf_fifo_head (oi->obuf);
627 assert (op);
628 assert (op->length >= OSPF_HEADER_SIZE);
629
paul68980082003-03-25 05:07:42 +0000630 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
631 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000632 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
633
paul718e3742002-12-13 20:15:29 +0000634 /* Rewrite the md5 signature & update the seq */
635 ospf_make_md5_digest (oi, op);
636
paul37ccfa32004-10-31 11:24:51 +0000637 /* Retrieve OSPF packet type. */
638 stream_set_getp (op->s, 1);
639 type = stream_getc (op->s);
640
paul68b73392004-09-12 14:21:37 +0000641 /* reset get pointer */
642 stream_set_getp (op->s, 0);
643
644 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000645 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000646
paul718e3742002-12-13 20:15:29 +0000647 sa_dst.sin_family = AF_INET;
648#ifdef HAVE_SIN_LEN
649 sa_dst.sin_len = sizeof(sa_dst);
650#endif /* HAVE_SIN_LEN */
651 sa_dst.sin_addr = op->dst;
652 sa_dst.sin_port = htons (0);
653
654 /* Set DONTROUTE flag if dst is unicast. */
655 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
656 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
657 flags = MSG_DONTROUTE;
658
paul68b73392004-09-12 14:21:37 +0000659 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
660 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000661 if ( sizeof (struct ip)
662 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000663 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
664
paul718e3742002-12-13 20:15:29 +0000665 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000666 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000667 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000668
paul0bfeca32004-09-24 08:07:54 +0000669#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000670 /* XXX-MT: not thread-safe at all..
671 * XXX: this presumes this is only programme sending OSPF packets
672 * otherwise, no guarantee ipid will be unique
673 */
674 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000675#endif /* WANT_OSPF_WRITE_FRAGMENT */
676
paul718e3742002-12-13 20:15:29 +0000677 iph.ip_off = 0;
678 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
679 iph.ip_ttl = OSPF_VL_IP_TTL;
680 else
681 iph.ip_ttl = OSPF_IP_TTL;
682 iph.ip_p = IPPROTO_OSPFIGP;
683 iph.ip_sum = 0;
684 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
685 iph.ip_dst.s_addr = op->dst.s_addr;
686
687 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000688 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000689 msg.msg_namelen = sizeof (sa_dst);
690 msg.msg_iov = iov;
691 msg.msg_iovlen = 2;
692 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000693 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
694 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000695 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000696
697 /* Sadly we can not rely on kernels to fragment packets because of either
698 * IP_HDRINCL and/or multicast destination being set.
699 */
paul0bfeca32004-09-24 08:07:54 +0000700#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000701 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000702 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
703 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000704#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000705
706 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000707 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000708 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000709 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000710
711 if (ret < 0)
paul68b73392004-09-12 14:21:37 +0000712 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
ajs6099b3b2004-11-20 02:06:59 +0000713 inet_ntoa (iph.ip_dst), safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000714
paul718e3742002-12-13 20:15:29 +0000715 /* Show debug sending packet. */
716 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
717 {
718 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
719 {
ajs2a42e282004-12-08 18:43:03 +0000720 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000721 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000722 stream_set_getp (op->s, 0);
723 ospf_packet_dump (op->s);
724 }
725
ajs2a42e282004-12-08 18:43:03 +0000726 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000727 ospf_packet_type_str[type], inet_ntoa (op->dst),
728 IF_NAME (oi));
729
730 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000731 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000732 }
733
734 /* Now delete packet from queue. */
735 ospf_packet_delete (oi);
736
737 if (ospf_fifo_head (oi->obuf) == NULL)
738 {
739 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000740 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000741 }
742
743 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000744 if (!list_isempty (ospf->oi_write_q))
745 ospf->t_write =
746 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000747
748 return 0;
749}
750
751/* OSPF Hello message read -- RFC2328 Section 10.5. */
752void
753ospf_hello (struct ip *iph, struct ospf_header *ospfh,
754 struct stream * s, struct ospf_interface *oi, int size)
755{
756 struct ospf_hello *hello;
757 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000758 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000759 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000760
761 /* increment statistics. */
762 oi->hello_in++;
763
764 hello = (struct ospf_hello *) STREAM_PNT (s);
765
766 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000767 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000768 {
769 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
770 {
ajs2a42e282004-12-08 18:43:03 +0000771 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000772 "dropping.",
773 ospf_packet_type_str[ospfh->type],
774 inet_ntoa (iph->ip_src));
775 }
776 return;
777 }
paul718e3742002-12-13 20:15:29 +0000778
779 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000780 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
paulc2191ea2003-04-18 23:59:35 +0000781 zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
782 inet_ntoa (ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000783 return;
paulf2c80652002-12-13 21:44:27 +0000784 }
paul718e3742002-12-13 20:15:29 +0000785
786 /* get neighbor prefix. */
787 p.family = AF_INET;
788 p.prefixlen = ip_masklen (hello->network_mask);
789 p.u.prefix4 = iph->ip_src;
790
791 /* Compare network mask. */
792 /* Checking is ignored for Point-to-Point and Virtual link. */
793 if (oi->type != OSPF_IFTYPE_POINTOPOINT
794 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
795 if (oi->address->prefixlen != p.prefixlen)
796 {
797 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
798 inet_ntoa (ospfh->router_id));
799 return;
800 }
801
802 /* Compare Hello Interval. */
803 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
804 {
805 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
806 inet_ntoa (ospfh->router_id));
807 return;
808 }
809
810 /* Compare Router Dead Interval. */
811 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
812 {
813 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
814 inet_ntoa (ospfh->router_id));
815 return;
816 }
817
818 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000819 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000820 inet_ntoa (ospfh->router_id),
821 ospf_options_dump (hello->options));
822
823 /* Compare options. */
824#define REJECT_IF_TBIT_ON 1 /* XXX */
825#ifdef REJECT_IF_TBIT_ON
826 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
827 {
828 /*
829 * This router does not support non-zero TOS.
830 * Drop this Hello packet not to establish neighbor relationship.
831 */
832 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
833 inet_ntoa (ospfh->router_id));
834 return;
835 }
836#endif /* REJECT_IF_TBIT_ON */
837
838#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000839 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000840 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
841 {
842 /*
843 * This router does know the correct usage of O-bit
844 * the bit should be set in DD packet only.
845 */
846 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
847 inet_ntoa (ospfh->router_id));
848#ifdef STRICT_OBIT_USAGE_CHECK
849 return; /* Reject this packet. */
850#else /* STRICT_OBIT_USAGE_CHECK */
851 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
852#endif /* STRICT_OBIT_USAGE_CHECK */
853 }
854#endif /* HAVE_OPAQUE_LSA */
855
856 /* new for NSSA is to ensure that NP is on and E is off */
857
paul718e3742002-12-13 20:15:29 +0000858 if (oi->area->external_routing == OSPF_AREA_NSSA)
859 {
860 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
861 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
862 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
863 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
864 {
865 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
866 return;
867 }
868 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000869 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000870 }
871 else
paul718e3742002-12-13 20:15:29 +0000872 /* The setting of the E-bit found in the Hello Packet's Options
873 field must match this area's ExternalRoutingCapability A
874 mismatch causes processing to stop and the packet to be
875 dropped. The setting of the rest of the bits in the Hello
876 Packet's Options field should be ignored. */
877 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
878 CHECK_FLAG (hello->options, OSPF_OPTION_E))
879 {
ajs3aa8d5f2004-12-11 18:00:06 +0000880 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
881 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000882 return;
883 }
paul718e3742002-12-13 20:15:29 +0000884
pauld3f0d622004-05-05 15:27:15 +0000885 /* get neighbour struct */
886 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
887
888 /* neighbour must be valid, ospf_nbr_get creates if none existed */
889 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000890
891 old_state = nbr->state;
892
893 /* Add event to thread. */
894 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
895
896 /* RFC2328 Section 9.5.1
897 If the router is not eligible to become Designated Router,
898 (snip) It must also send an Hello Packet in reply to an
899 Hello Packet received from any eligible neighbor (other than
900 the current Designated Router and Backup Designated Router). */
901 if (oi->type == OSPF_IFTYPE_NBMA)
902 if (PRIORITY(oi) == 0 && hello->priority > 0
903 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
904 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
905 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
906 OSPF_HELLO_REPLY_DELAY);
907
908 /* on NBMA network type, it happens to receive bidirectional Hello packet
909 without advance 1-Way Received event.
910 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
911 if (oi->type == OSPF_IFTYPE_NBMA &&
912 (old_state == NSM_Down || old_state == NSM_Attempt))
913 {
914 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
915 nbr->priority = hello->priority;
916 nbr->d_router = hello->d_router;
917 nbr->bd_router = hello->bd_router;
918 return;
919 }
920
paul68980082003-03-25 05:07:42 +0000921 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000922 size - OSPF_HELLO_MIN_SIZE))
923 {
924 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
925 nbr->options |= hello->options;
926 }
927 else
928 {
929 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
930 /* Set neighbor information. */
931 nbr->priority = hello->priority;
932 nbr->d_router = hello->d_router;
933 nbr->bd_router = hello->bd_router;
934 return;
935 }
936
937 /* If neighbor itself declares DR and no BDR exists,
938 cause event BackupSeen */
939 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
940 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
941 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
942
943 /* neighbor itself declares BDR. */
944 if (oi->state == ISM_Waiting &&
945 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
946 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
947
948 /* had not previously. */
949 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
950 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
951 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
952 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
953 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
954
955 /* had not previously. */
956 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
957 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
958 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
959 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
960 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
961
962 /* Neighbor priority check. */
963 if (nbr->priority >= 0 && nbr->priority != hello->priority)
964 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
965
966 /* Set neighbor information. */
967 nbr->priority = hello->priority;
968 nbr->d_router = hello->d_router;
969 nbr->bd_router = hello->bd_router;
970}
971
972/* Save DD flags/options/Seqnum received. */
973void
974ospf_db_desc_save_current (struct ospf_neighbor *nbr,
975 struct ospf_db_desc *dd)
976{
977 nbr->last_recv.flags = dd->flags;
978 nbr->last_recv.options = dd->options;
979 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
980}
981
982/* Process rest of DD packet. */
983static void
984ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
985 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
986 u_int16_t size)
987{
988 struct ospf_lsa *new, *find;
989 struct lsa_header *lsah;
990
991 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
992 for (size -= OSPF_DB_DESC_MIN_SIZE;
993 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
994 {
995 lsah = (struct lsa_header *) STREAM_PNT (s);
996 stream_forward (s, OSPF_LSA_HEADER_SIZE);
997
998 /* Unknown LS type. */
999 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1000 {
ajsbec595a2004-11-30 22:38:43 +00001001 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001002 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1003 return;
1004 }
1005
1006#ifdef HAVE_OPAQUE_LSA
1007 if (IS_OPAQUE_LSA (lsah->type)
1008 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1009 {
1010 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1011 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1012 return;
1013 }
1014#endif /* HAVE_OPAQUE_LSA */
1015
1016 switch (lsah->type)
1017 {
1018 case OSPF_AS_EXTERNAL_LSA:
1019#ifdef HAVE_OPAQUE_LSA
1020 case OSPF_OPAQUE_AS_LSA:
1021#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001022 /* Check for stub area. Reject if AS-External from stub but
1023 allow if from NSSA. */
1024 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001025 {
1026 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1027 lsah->type, inet_ntoa (lsah->id),
1028 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1029 "STUB" : "NSSA");
1030 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1031 return;
1032 }
1033 break;
1034 default:
1035 break;
1036 }
1037
1038 /* Create LS-request object. */
1039 new = ospf_ls_request_new (lsah);
1040
1041 /* Lookup received LSA, then add LS request list. */
1042 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1043 if (!find || ospf_lsa_more_recent (find, new) < 0)
1044 {
1045 ospf_ls_request_add (nbr, new);
1046 ospf_lsa_discard (new);
1047 }
1048 else
1049 {
1050 /* Received LSA is not recent. */
1051 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001052 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001053 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1054 ospf_lsa_discard (new);
1055 continue;
1056 }
1057 }
1058
1059 /* Master */
1060 if (IS_SET_DD_MS (nbr->dd_flags))
1061 {
1062 nbr->dd_seqnum++;
1063 /* Entire DD packet sent. */
1064 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1065 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1066 else
1067 /* Send new DD packet. */
1068 ospf_db_desc_send (nbr);
1069 }
1070 /* Slave */
1071 else
1072 {
1073 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1074
1075 /* When master's more flags is not set. */
1076 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1077 {
1078 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1079 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1080 }
1081
ajsbec595a2004-11-30 22:38:43 +00001082 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001083 ospf_db_desc_send (nbr);
1084 }
1085
1086 /* Save received neighbor values from DD. */
1087 ospf_db_desc_save_current (nbr, dd);
1088}
1089
1090int
1091ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1092{
1093 /* Is DD duplicated? */
1094 if (dd->options == nbr->last_recv.options &&
1095 dd->flags == nbr->last_recv.flags &&
1096 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1097 return 1;
1098
1099 return 0;
1100}
1101
1102/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001103static void
paul718e3742002-12-13 20:15:29 +00001104ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1105 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1106{
1107 struct ospf_db_desc *dd;
1108 struct ospf_neighbor *nbr;
1109
1110 /* Increment statistics. */
1111 oi->db_desc_in++;
1112
1113 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001114
pauld3f0d622004-05-05 15:27:15 +00001115 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001116 if (nbr == NULL)
1117 {
1118 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1119 inet_ntoa (ospfh->router_id));
1120 return;
1121 }
1122
1123 /* Check MTU. */
1124 if (ntohs (dd->mtu) > oi->ifp->mtu)
1125 {
ajs3aa8d5f2004-12-11 18:00:06 +00001126 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1127 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1128 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001129 return;
1130 }
1131
pauld363df22003-06-19 00:26:34 +00001132 /*
1133 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1134 * required. In fact at least JunOS sends DD packets with P bit clear.
1135 * Until proper solution is developped, this hack should help.
1136 *
1137 * Update: According to the RFCs, N bit is specified /only/ for Hello
1138 * options, unfortunately its use in DD options is not specified. Hence some
1139 * implementations follow E-bit semantics and set it in DD options, and some
1140 * treat it as unspecified and hence follow the directive "default for
1141 * options is clear", ie unset.
1142 *
1143 * Reset the flag, as ospfd follows E-bit semantics.
1144 */
1145 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1146 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1147 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1148 {
1149 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001150 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001151 inet_ntoa (nbr->router_id) );
1152 SET_FLAG (dd->options, OSPF_OPTION_NP);
1153 }
pauld363df22003-06-19 00:26:34 +00001154
paul718e3742002-12-13 20:15:29 +00001155#ifdef REJECT_IF_TBIT_ON
1156 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1157 {
1158 /*
1159 * In Hello protocol, optional capability must have checked
1160 * to prevent this T-bit enabled router be my neighbor.
1161 */
1162 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1163 return;
1164 }
1165#endif /* REJECT_IF_TBIT_ON */
1166
1167#ifdef HAVE_OPAQUE_LSA
1168 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001169 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001170 {
1171 /*
1172 * This node is not configured to handle O-bit, for now.
1173 * Clear it to ignore unsupported capability proposed by neighbor.
1174 */
1175 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1176 }
1177#endif /* HAVE_OPAQUE_LSA */
1178
1179 /* Process DD packet by neighbor status. */
1180 switch (nbr->state)
1181 {
1182 case NSM_Down:
1183 case NSM_Attempt:
1184 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001185 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001186 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001187 LOOKUP (ospf_nsm_state_msg, nbr->state));
1188 break;
1189 case NSM_Init:
1190 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1191 /* If the new state is ExStart, the processing of the current
1192 packet should then continue in this new state by falling
1193 through to case ExStart below. */
1194 if (nbr->state != NSM_ExStart)
1195 break;
1196 case NSM_ExStart:
1197 /* Initial DBD */
1198 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1199 (size == OSPF_DB_DESC_MIN_SIZE))
1200 {
paul68980082003-03-25 05:07:42 +00001201 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001202 {
1203 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001204 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001205 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001206 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1207 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1208 }
1209 else
1210 {
1211 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001212 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1213 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001214 break;
1215 }
1216 }
1217 /* Ack from the Slave */
1218 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1219 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001220 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001221 {
ajs17eaa722004-12-29 21:04:48 +00001222 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001223 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001224 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1225 }
1226 else
1227 {
ajs3aa8d5f2004-12-11 18:00:06 +00001228 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1229 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001230 break;
1231 }
1232
1233 /* This is where the real Options are saved */
1234 nbr->options = dd->options;
1235
1236#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001237 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001238 {
1239 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001240 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001241 inet_ntoa (nbr->router_id),
1242 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1243
1244 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1245 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1246 {
1247 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1248 /* This situation is undesirable, but not a real error. */
1249 }
1250 }
1251#endif /* HAVE_OPAQUE_LSA */
1252
1253 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1254
1255 /* continue processing rest of packet. */
1256 ospf_db_desc_proc (s, oi, nbr, dd, size);
1257 break;
1258 case NSM_Exchange:
1259 if (ospf_db_desc_is_dup (dd, nbr))
1260 {
1261 if (IS_SET_DD_MS (nbr->dd_flags))
1262 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001263 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1264 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001265 else
1266 /* Slave: cause to retransmit the last Database Description. */
1267 {
ajs3aa8d5f2004-12-11 18:00:06 +00001268 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1269 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001270 ospf_db_desc_resend (nbr);
1271 }
1272 break;
1273 }
1274
1275 /* Otherwise DD packet should be checked. */
1276 /* Check Master/Slave bit mismatch */
1277 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1278 {
ajs3aa8d5f2004-12-11 18:00:06 +00001279 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1280 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001281 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1282 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001283 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001284 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001285 break;
1286 }
1287
1288 /* Check initialize bit is set. */
1289 if (IS_SET_DD_I (dd->flags))
1290 {
ajs3aa8d5f2004-12-11 18:00:06 +00001291 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1292 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001293 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1294 break;
1295 }
1296
1297 /* Check DD Options. */
1298 if (dd->options != nbr->options)
1299 {
1300#ifdef ORIGINAL_CODING
1301 /* Save the new options for debugging */
1302 nbr->options = dd->options;
1303#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001304 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1305 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001306 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1307 break;
1308 }
1309
1310 /* Check DD sequence number. */
1311 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1312 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1313 (!IS_SET_DD_MS (nbr->dd_flags) &&
1314 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1315 {
ajs3aa8d5f2004-12-11 18:00:06 +00001316 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1317 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001318 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1319 break;
1320 }
1321
1322 /* Continue processing rest of packet. */
1323 ospf_db_desc_proc (s, oi, nbr, dd, size);
1324 break;
1325 case NSM_Loading:
1326 case NSM_Full:
1327 if (ospf_db_desc_is_dup (dd, nbr))
1328 {
1329 if (IS_SET_DD_MS (nbr->dd_flags))
1330 {
1331 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001332 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1333 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001334 break;
1335 }
1336 else
1337 {
1338 struct timeval t, now;
1339 gettimeofday (&now, NULL);
1340 t = tv_sub (now, nbr->last_send_ts);
1341 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1342 {
1343 /* In states Loading and Full the slave must resend
1344 its last Database Description packet in response to
1345 duplicate Database Description packets received
1346 from the master. For this reason the slave must
1347 wait RouterDeadInterval seconds before freeing the
1348 last Database Description packet. Reception of a
1349 Database Description packet from the master after
1350 this interval will generate a SeqNumberMismatch
1351 neighbor event. RFC2328 Section 10.8 */
1352 ospf_db_desc_resend (nbr);
1353 break;
1354 }
1355 }
1356 }
1357
1358 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1359 break;
1360 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001361 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1362 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001363 break;
1364 }
1365}
1366
1367#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1368
1369/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1370void
1371ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1372 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1373{
1374 struct ospf_neighbor *nbr;
1375 u_int32_t ls_type;
1376 struct in_addr ls_id;
1377 struct in_addr adv_router;
1378 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001379 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001380 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001381
1382 /* Increment statistics. */
1383 oi->ls_req_in++;
1384
pauld3f0d622004-05-05 15:27:15 +00001385 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001386 if (nbr == NULL)
1387 {
1388 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1389 inet_ntoa (ospfh->router_id));
1390 return;
1391 }
1392
1393 /* Neighbor State should be Exchange or later. */
1394 if (nbr->state != NSM_Exchange &&
1395 nbr->state != NSM_Loading &&
1396 nbr->state != NSM_Full)
1397 {
ajsbec595a2004-11-30 22:38:43 +00001398 zlog_warn ("Link State Request received from %s: "
1399 "Neighbor state is %s, packet discarded.",
1400 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001401 LOOKUP (ospf_nsm_state_msg, nbr->state));
1402 return;
1403 }
1404
1405 /* Send Link State Update for ALL requested LSAs. */
1406 ls_upd = list_new ();
1407 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1408
1409 while (size >= OSPF_LSA_KEY_SIZE)
1410 {
1411 /* Get one slice of Link State Request. */
1412 ls_type = stream_getl (s);
1413 ls_id.s_addr = stream_get_ipv4 (s);
1414 adv_router.s_addr = stream_get_ipv4 (s);
1415
1416 /* Verify LSA type. */
1417 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1418 {
1419 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1420 list_delete (ls_upd);
1421 return;
1422 }
1423
1424 /* Search proper LSA in LSDB. */
1425 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1426 if (find == NULL)
1427 {
1428 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1429 list_delete (ls_upd);
1430 return;
1431 }
1432
gdt86f1fd92005-01-10 14:20:43 +00001433 /* Packet overflows MTU size, send immediately. */
1434 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001435 {
1436 if (oi->type == OSPF_IFTYPE_NBMA)
1437 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1438 else
1439 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1440
1441 /* Only remove list contents. Keep ls_upd. */
1442 list_delete_all_node (ls_upd);
1443
1444 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1445 }
1446
1447 /* Append LSA to update list. */
1448 listnode_add (ls_upd, find);
1449 length += ntohs (find->data->length);
1450
1451 size -= OSPF_LSA_KEY_SIZE;
1452 }
1453
1454 /* Send rest of Link State Update. */
1455 if (listcount (ls_upd) > 0)
1456 {
1457 if (oi->type == OSPF_IFTYPE_NBMA)
1458 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1459 else
1460 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1461
1462 list_delete (ls_upd);
1463 }
1464 else
1465 list_free (ls_upd);
1466}
1467
1468/* Get the list of LSAs from Link State Update packet.
1469 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001470static struct list *
paul718e3742002-12-13 20:15:29 +00001471ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1472 struct ospf_interface *oi, size_t size)
1473{
1474 u_int16_t count, sum;
1475 u_int32_t length;
1476 struct lsa_header *lsah;
1477 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001478 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001479
1480 lsas = list_new ();
1481
1482 count = stream_getl (s);
1483 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1484
1485 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1486 size -= length, stream_forward (s, length), count--)
1487 {
1488 lsah = (struct lsa_header *) STREAM_PNT (s);
1489 length = ntohs (lsah->length);
1490
1491 if (length > size)
1492 {
1493 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1494 break;
1495 }
1496
1497 /* Validate the LSA's LS checksum. */
1498 sum = lsah->checksum;
1499 if (sum != ospf_lsa_checksum (lsah))
1500 {
1501 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1502 sum, lsah->checksum);
1503 continue;
1504 }
1505
1506 /* Examine the LSA's LS type. */
1507 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1508 {
1509 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1510 continue;
1511 }
1512
1513 /*
1514 * What if the received LSA's age is greater than MaxAge?
1515 * Treat it as a MaxAge case -- endo.
1516 */
1517 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1518 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1519
1520#ifdef HAVE_OPAQUE_LSA
1521 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1522 {
1523#ifdef STRICT_OBIT_USAGE_CHECK
1524 if ((IS_OPAQUE_LSA(lsah->type) &&
1525 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1526 || (! IS_OPAQUE_LSA(lsah->type) &&
1527 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1528 {
1529 /*
1530 * This neighbor must know the exact usage of O-bit;
1531 * the bit will be set in Type-9,10,11 LSAs only.
1532 */
1533 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1534 continue;
1535 }
1536#endif /* STRICT_OBIT_USAGE_CHECK */
1537
1538 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1539 if (lsah->type == OSPF_OPAQUE_AS_LSA
1540 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1541 {
1542 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001543 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
paul718e3742002-12-13 20:15:29 +00001544 continue;
1545 }
1546 }
1547 else if (IS_OPAQUE_LSA(lsah->type))
1548 {
1549 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1550 continue;
1551 }
1552#endif /* HAVE_OPAQUE_LSA */
1553
1554 /* Create OSPF LSA instance. */
1555 lsa = ospf_lsa_new ();
1556
1557 /* We may wish to put some error checking if type NSSA comes in
1558 and area not in NSSA mode */
1559 switch (lsah->type)
1560 {
1561 case OSPF_AS_EXTERNAL_LSA:
1562#ifdef HAVE_OPAQUE_LSA
1563 case OSPF_OPAQUE_AS_LSA:
1564 lsa->area = NULL;
1565 break;
1566 case OSPF_OPAQUE_LINK_LSA:
1567 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1568 /* Fallthrough */
1569#endif /* HAVE_OPAQUE_LSA */
1570 default:
1571 lsa->area = oi->area;
1572 break;
1573 }
1574
1575 lsa->data = ospf_lsa_data_new (length);
1576 memcpy (lsa->data, lsah, length);
1577
1578 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001579 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001580 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1581 listnode_add (lsas, lsa);
1582 }
1583
1584 return lsas;
1585}
1586
1587/* Cleanup Update list. */
1588void
hasso52dc7ee2004-09-23 19:18:23 +00001589ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001590{
hasso52dc7ee2004-09-23 19:18:23 +00001591 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001592 struct ospf_lsa *lsa;
1593
1594 for (node = listhead (lsas); node; nextnode (node))
1595 if ((lsa = getdata (node)) != NULL)
1596 ospf_lsa_discard (lsa);
1597
1598 list_delete (lsas);
1599}
1600
1601/* OSPF Link State Update message read -- RFC2328 Section 13. */
1602void
1603ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1604 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1605{
1606 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001607 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001608#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001609 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001610#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001611 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001612 struct ospf_lsa *lsa = NULL;
1613 /* unsigned long ls_req_found = 0; */
1614
1615 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1616
1617 /* Increment statistics. */
1618 oi->ls_upd_in++;
1619
1620 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001621 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001622 if (nbr == NULL)
1623 {
1624 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1625 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1626 return;
1627 }
1628
1629 /* Check neighbor state. */
1630 if (nbr->state < NSM_Exchange)
1631 {
ajs3aa8d5f2004-12-11 18:00:06 +00001632 zlog_warn ("Link State Update: "
1633 "Neighbor[%s] state %s is less than Exchange",
1634 inet_ntoa (ospfh->router_id),
1635 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001636 return;
1637 }
1638
1639 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1640 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1641 * of section 13.
1642 */
1643 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1644
1645#ifdef HAVE_OPAQUE_LSA
1646 /*
1647 * Prepare two kinds of lists to clean up unwanted self-originated
1648 * Opaque-LSAs from the routing domain as soon as possible.
1649 */
1650 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1651 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1652
1653 /*
1654 * If self-originated Opaque-LSAs that have flooded before restart
1655 * are contained in the received LSUpd message, corresponding LSReq
1656 * messages to be sent may have to be modified.
1657 * To eliminate possible race conditions such that flushing and normal
1658 * updating for the same LSA would take place alternately, this trick
1659 * must be done before entering to the loop below.
1660 */
1661 ospf_opaque_adjust_lsreq (nbr, lsas);
1662#endif /* HAVE_OPAQUE_LSA */
1663
1664#define DISCARD_LSA(L,N) {\
1665 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001666 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
paul718e3742002-12-13 20:15:29 +00001667 ospf_lsa_discard (L); \
1668 continue; }
1669
1670 /* Process each LSA received in the one packet. */
1671 for (node = listhead (lsas); node; node = next)
1672 {
1673 struct ospf_lsa *ls_ret, *current;
1674 int ret = 1;
1675
1676 next = node->next;
1677
1678 lsa = getdata (node);
1679
paul718e3742002-12-13 20:15:29 +00001680 if (IS_DEBUG_OSPF_NSSA)
1681 {
1682 char buf1[INET_ADDRSTRLEN];
1683 char buf2[INET_ADDRSTRLEN];
1684 char buf3[INET_ADDRSTRLEN];
1685
ajs2a42e282004-12-08 18:43:03 +00001686 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001687 lsa->data->type,
1688 inet_ntop (AF_INET, &ospfh->router_id,
1689 buf1, INET_ADDRSTRLEN),
1690 inet_ntop (AF_INET, &lsa->data->id,
1691 buf2, INET_ADDRSTRLEN),
1692 inet_ntop (AF_INET, &lsa->data->adv_router,
1693 buf3, INET_ADDRSTRLEN));
1694 }
paul718e3742002-12-13 20:15:29 +00001695
1696 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1697
1698 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1699
1700 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1701
1702 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1703
1704 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1705
1706 /* Do take in Type-7's if we are an NSSA */
1707
1708 /* If we are also an ABR, later translate them to a Type-5 packet */
1709
1710 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1711 translate them to a separate Type-5 packet. */
1712
1713 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1714 /* Reject from STUB or NSSA */
1715 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1716 {
1717 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001718 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001719 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001720 }
1721
paul718e3742002-12-13 20:15:29 +00001722 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1723 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1724 {
1725 DISCARD_LSA (lsa,2);
1726 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001727 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001728 }
paul718e3742002-12-13 20:15:29 +00001729
1730 /* Find the LSA in the current database. */
1731
1732 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1733
1734 /* If the LSA's LS age is equal to MaxAge, and there is currently
1735 no instance of the LSA in the router's link state database,
1736 and none of router's neighbors are in states Exchange or Loading,
1737 then take the following actions. */
1738
1739 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001740 (ospf_nbr_count (oi, NSM_Exchange) +
1741 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001742 {
1743 /* Response Link State Acknowledgment. */
1744 ospf_ls_ack_send (nbr, lsa);
1745
1746 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001747 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1748 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001749 DISCARD_LSA (lsa, 3);
1750 }
1751
1752#ifdef HAVE_OPAQUE_LSA
1753 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001754 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001755 {
1756 /*
1757 * Even if initial flushing seems to be completed, there might
1758 * be a case that self-originated LSA with MaxAge still remain
1759 * in the routing domain.
1760 * Just send an LSAck message to cease retransmission.
1761 */
1762 if (IS_LSA_MAXAGE (lsa))
1763 {
1764 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1765 ospf_ls_ack_send (nbr, lsa);
1766 ospf_lsa_discard (lsa);
1767
1768 if (current != NULL && ! IS_LSA_MAXAGE (current))
1769 ospf_opaque_lsa_refresh_schedule (current);
1770 continue;
1771 }
1772
1773 /*
1774 * If an instance of self-originated Opaque-LSA is not found
1775 * in the LSDB, there are some possible cases here.
1776 *
1777 * 1) This node lost opaque-capability after restart.
1778 * 2) Else, a part of opaque-type is no more supported.
1779 * 3) Else, a part of opaque-id is no more supported.
1780 *
1781 * Anyway, it is still this node's responsibility to flush it.
1782 * Otherwise, the LSA instance remains in the routing domain
1783 * until its age reaches to MaxAge.
1784 */
1785 if (current == NULL)
1786 {
1787 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001788 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001789
1790 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1791 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1792 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1793 continue;
1794 }
1795 }
1796#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001797 /* It might be happen that received LSA is self-originated network LSA, but
1798 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1799 * Link State ID is one of the router's own IP interface addresses but whose
1800 * Advertising Router is not equal to the router's own Router ID
1801 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1802 */
1803
1804 if(lsa->data->type == OSPF_NETWORK_LSA)
1805 {
hasso52dc7ee2004-09-23 19:18:23 +00001806 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001807 int Flag = 0;
1808
1809 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1810 {
1811 struct ospf_interface *out_if = getdata(oi_node);
1812 if(out_if == NULL)
1813 break;
1814
1815 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1816 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1817 {
1818 if(out_if->network_lsa_self)
1819 {
1820 ospf_lsa_flush_area(lsa,out_if->area);
1821 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001822 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001823 lsa, (int) lsa->data->type);
1824 ospf_lsa_discard (lsa);
1825 Flag = 1;
1826 }
1827 break;
1828 }
1829 }
1830 if(Flag)
1831 continue;
1832 }
paul718e3742002-12-13 20:15:29 +00001833
1834 /* (5) Find the instance of this LSA that is currently contained
1835 in the router's link state database. If there is no
1836 database copy, or the received LSA is more recent than
1837 the database copy the following steps must be performed. */
1838
1839 if (current == NULL ||
1840 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1841 {
1842 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001843 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001844 DISCARD_LSA (lsa, 4);
1845 continue;
1846 }
1847
1848 /* (6) Else, If there is an instance of the LSA on the sending
1849 neighbor's Link state request list, an error has occurred in
1850 the Database Exchange process. In this case, restart the
1851 Database Exchange process by generating the neighbor event
1852 BadLSReq for the sending neighbor and stop processing the
1853 Link State Update packet. */
1854
1855 if (ospf_ls_request_lookup (nbr, lsa))
1856 {
1857 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001858 zlog_warn("LSA[%s] instance exists on Link state request list",
1859 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001860
1861 /* Clean list of LSAs. */
1862 ospf_upd_list_clean (lsas);
1863 /* this lsa is not on lsas list already. */
1864 ospf_lsa_discard (lsa);
1865#ifdef HAVE_OPAQUE_LSA
1866 list_delete (mylsa_acks);
1867 list_delete (mylsa_upds);
1868#endif /* HAVE_OPAQUE_LSA */
1869 return;
1870 }
1871
1872 /* If the received LSA is the same instance as the database copy
1873 (i.e., neither one is more recent) the following two steps
1874 should be performed: */
1875
1876 if (ret == 0)
1877 {
1878 /* If the LSA is listed in the Link state retransmission list
1879 for the receiving adjacency, the router itself is expecting
1880 an acknowledgment for this LSA. The router should treat the
1881 received LSA as an acknowledgment by removing the LSA from
1882 the Link state retransmission list. This is termed an
1883 "implied acknowledgment". */
1884
1885 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1886
1887 if (ls_ret != NULL)
1888 {
1889 ospf_ls_retransmit_delete (nbr, ls_ret);
1890
1891 /* Delayed acknowledgment sent if advertisement received
1892 from Designated Router, otherwise do nothing. */
1893 if (oi->state == ISM_Backup)
1894 if (NBR_IS_DR (nbr))
1895 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1896
1897 DISCARD_LSA (lsa, 5);
1898 }
1899 else
1900 /* Acknowledge the receipt of the LSA by sending a
1901 Link State Acknowledgment packet back out the receiving
1902 interface. */
1903 {
1904 ospf_ls_ack_send (nbr, lsa);
1905 DISCARD_LSA (lsa, 6);
1906 }
1907 }
1908
1909 /* The database copy is more recent. If the database copy
1910 has LS age equal to MaxAge and LS sequence number equal to
1911 MaxSequenceNumber, simply discard the received LSA without
1912 acknowledging it. (In this case, the LSA's LS sequence number is
1913 wrapping, and the MaxSequenceNumber LSA must be completely
1914 flushed before any new LSA instance can be introduced). */
1915
1916 else if (ret > 0) /* Database copy is more recent */
1917 {
1918 if (IS_LSA_MAXAGE (current) &&
1919 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1920 {
1921 DISCARD_LSA (lsa, 7);
1922 }
1923 /* Otherwise, as long as the database copy has not been sent in a
1924 Link State Update within the last MinLSArrival seconds, send the
1925 database copy back to the sending neighbor, encapsulated within
1926 a Link State Update Packet. The Link State Update Packet should
1927 be sent directly to the neighbor. In so doing, do not put the
1928 database copy of the LSA on the neighbor's link state
1929 retransmission list, and do not acknowledge the received (less
1930 recent) LSA instance. */
1931 else
1932 {
1933 struct timeval now;
1934
1935 gettimeofday (&now, NULL);
1936
1937 if (tv_cmp (tv_sub (now, current->tv_orig),
1938 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1939 /* Trap NSSA type later.*/
1940 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1941 DISCARD_LSA (lsa, 8);
1942 }
1943 }
1944 }
1945
1946#ifdef HAVE_OPAQUE_LSA
1947 /*
1948 * Now that previously originated Opaque-LSAs those which not yet
1949 * installed into LSDB are captured, take several steps to clear
1950 * them completely from the routing domain, before proceeding to
1951 * origination for the current target Opaque-LSAs.
1952 */
1953 while (listcount (mylsa_acks) > 0)
1954 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1955
1956 if (listcount (mylsa_upds) > 0)
1957 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1958
1959 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001960 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001961#endif /* HAVE_OPAQUE_LSA */
1962
1963 assert (listcount (lsas) == 0);
1964 list_delete (lsas);
1965}
1966
1967/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1968void
1969ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1970 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1971{
1972 struct ospf_neighbor *nbr;
1973#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001974 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001975#endif /* HAVE_OPAQUE_LSA */
1976
1977 /* increment statistics. */
1978 oi->ls_ack_in++;
1979
pauld3f0d622004-05-05 15:27:15 +00001980 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001981 if (nbr == NULL)
1982 {
1983 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1984 inet_ntoa (ospfh->router_id));
1985 return;
1986 }
1987
1988 if (nbr->state < NSM_Exchange)
1989 {
ajs3aa8d5f2004-12-11 18:00:06 +00001990 zlog_warn ("Link State Acknowledgment: "
1991 "Neighbor[%s] state %s is less than Exchange",
1992 inet_ntoa (ospfh->router_id),
1993 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001994 return;
1995 }
1996
1997#ifdef HAVE_OPAQUE_LSA
1998 opaque_acks = list_new ();
1999#endif /* HAVE_OPAQUE_LSA */
2000
2001 while (size >= OSPF_LSA_HEADER_SIZE)
2002 {
2003 struct ospf_lsa *lsa, *lsr;
2004
2005 lsa = ospf_lsa_new ();
2006 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2007
2008 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2009 size -= OSPF_LSA_HEADER_SIZE;
2010 stream_forward (s, OSPF_LSA_HEADER_SIZE);
2011
2012 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2013 {
2014 lsa->data = NULL;
2015 ospf_lsa_discard (lsa);
2016 continue;
2017 }
2018
2019 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2020
2021 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2022 {
2023#ifdef HAVE_OPAQUE_LSA
2024 /* Keep this LSA entry for later reference. */
2025 if (IS_OPAQUE_LSA (lsr->data->type))
2026 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2027#endif /* HAVE_OPAQUE_LSA */
2028
2029 ospf_ls_retransmit_delete (nbr, lsr);
2030 }
2031
2032 lsa->data = NULL;
2033 ospf_lsa_discard (lsa);
2034 }
2035
2036#ifdef HAVE_OPAQUE_LSA
2037 if (listcount (opaque_acks) > 0)
2038 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2039
2040 list_delete (opaque_acks);
2041 return;
2042#endif /* HAVE_OPAQUE_LSA */
2043}
2044
2045struct stream *
2046ospf_recv_packet (int fd, struct interface **ifp)
2047{
2048 int ret;
2049 struct ip iph;
2050 u_int16_t ip_len;
2051 struct stream *ibuf;
2052 unsigned int ifindex = 0;
2053 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002054 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002055 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002056 struct msghdr msgh;
2057
paul68defd62004-09-27 07:27:13 +00002058 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002059 msgh.msg_iov = &iov;
2060 msgh.msg_iovlen = 1;
2061 msgh.msg_control = (caddr_t) buff;
2062 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002063
paul718e3742002-12-13 20:15:29 +00002064 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2065
2066 if (ret != sizeof (iph))
2067 {
2068 zlog_warn ("ospf_recv_packet packet smaller than ip header");
gdtbe210242004-12-29 20:12:59 +00002069 /* XXX: We peeked, and thus perhaps should discard this packet. */
paul718e3742002-12-13 20:15:29 +00002070 return NULL;
2071 }
paul18b12c32004-10-05 14:38:29 +00002072
2073 sockopt_iphdrincl_swab_systoh (&iph);
2074
paul6b333612004-10-11 10:11:25 +00002075 ip_len = iph.ip_len;
2076
paul239aecc2003-12-08 10:34:54 +00002077#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002078 /*
2079 * Kernel network code touches incoming IP header parameters,
2080 * before protocol specific processing.
2081 *
2082 * 1) Convert byteorder to host representation.
2083 * --> ip_len, ip_id, ip_off
2084 *
2085 * 2) Adjust ip_len to strip IP header size!
2086 * --> If user process receives entire IP packet via RAW
2087 * socket, it must consider adding IP header size to
2088 * the "ip_len" field of "ip" structure.
2089 *
2090 * For more details, see <netinet/ip_input.c>.
2091 */
2092 ip_len = ip_len + (iph.ip_hl << 2);
2093#endif
2094
2095 ibuf = stream_new (ip_len);
2096 iov.iov_base = STREAM_DATA (ibuf);
2097 iov.iov_len = ip_len;
2098 ret = recvmsg (fd, &msgh, 0);
2099
paul863082d2004-08-19 04:43:43 +00002100 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002101
2102 *ifp = if_lookup_by_index (ifindex);
2103
2104 if (ret != ip_len)
2105 {
2106 zlog_warn ("ospf_recv_packet short read. "
2107 "ip_len %d bytes read %d", ip_len, ret);
2108 stream_free (ibuf);
2109 return NULL;
2110 }
2111
2112 return ibuf;
2113}
2114
2115struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002116ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002117 struct ip *iph, struct ospf_header *ospfh)
2118{
2119 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002120 struct ospf_vl_data *vl_data;
2121 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002122 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002123
2124 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2125 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002126 return NULL;
paul718e3742002-12-13 20:15:29 +00002127
pauld3f0d622004-05-05 15:27:15 +00002128 /* look for local OSPF interface matching the destination
2129 * to determine Area ID. We presume therefore the destination address
2130 * is unique, or at least (for "unnumbered" links), not used in other
2131 * areas
2132 */
2133 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2134 iph->ip_dst)) == NULL)
2135 return NULL;
paul718e3742002-12-13 20:15:29 +00002136
paul020709f2003-04-04 02:44:16 +00002137 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002138 {
2139 if ((vl_data = getdata (node)) == NULL)
2140 continue;
2141
paul020709f2003-04-04 02:44:16 +00002142 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002143 if (!vl_area)
2144 continue;
2145
2146 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2147 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2148 {
2149 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002150 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002151 IF_NAME (vl_data->vl_oi));
2152 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2153 {
2154 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002155 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002156 return NULL;
2157 }
2158
2159 return vl_data->vl_oi;
2160 }
2161 }
2162
2163 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002164 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002165
pauld3f0d622004-05-05 15:27:15 +00002166 return NULL;
paul718e3742002-12-13 20:15:29 +00002167}
2168
2169int
2170ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2171{
2172 /* Check match the Area ID of the receiving interface. */
2173 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2174 return 1;
2175
2176 return 0;
2177}
2178
2179/* Unbound socket will accept any Raw IP packets if proto is matched.
2180 To prevent it, compare src IP address and i/f address with masking
2181 i/f network mask. */
2182int
2183ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2184{
2185 struct in_addr mask, me, him;
2186
2187 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2188 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2189 return 1;
2190
2191 masklen2ip (oi->address->prefixlen, &mask);
2192
2193 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2194 him.s_addr = ip_src.s_addr & mask.s_addr;
2195
2196 if (IPV4_ADDR_SAME (&me, &him))
2197 return 1;
2198
2199 return 0;
2200}
2201
2202int
2203ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2204 struct ospf_header *ospfh)
2205{
2206 int ret = 0;
2207 struct crypt_key *ck;
2208
2209 switch (ntohs (ospfh->auth_type))
2210 {
2211 case OSPF_AUTH_NULL:
2212 ret = 1;
2213 break;
2214 case OSPF_AUTH_SIMPLE:
2215 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2216 ret = 1;
2217 else
2218 ret = 0;
2219 break;
2220 case OSPF_AUTH_CRYPTOGRAPHIC:
2221 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2222 {
2223 ret = 0;
2224 break;
2225 }
2226
2227 /* This is very basic, the digest processing is elsewhere */
2228 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2229 ospfh->u.crypt.key_id == ck->key_id &&
2230 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2231 ret = 1;
2232 else
2233 ret = 0;
2234 break;
2235 default:
2236 ret = 0;
2237 break;
2238 }
2239
2240 return ret;
2241}
2242
2243int
2244ospf_check_sum (struct ospf_header *ospfh)
2245{
2246 u_int32_t ret;
2247 u_int16_t sum;
2248 int in_cksum (void *ptr, int nbytes);
2249
2250 /* clear auth_data for checksum. */
2251 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2252
2253 /* keep checksum and clear. */
2254 sum = ospfh->checksum;
2255 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2256
2257 /* calculate checksum. */
2258 ret = in_cksum (ospfh, ntohs (ospfh->length));
2259
2260 if (ret != sum)
2261 {
2262 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2263 ret, sum);
2264 return 0;
2265 }
2266
2267 return 1;
2268}
2269
2270/* OSPF Header verification. */
2271int
2272ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2273 struct ip *iph, struct ospf_header *ospfh)
2274{
2275 /* check version. */
2276 if (ospfh->version != OSPF_VERSION)
2277 {
2278 zlog_warn ("interface %s: ospf_read version number mismatch.",
2279 IF_NAME (oi));
2280 return -1;
2281 }
2282
2283 /* Check Area ID. */
2284 if (!ospf_check_area_id (oi, ospfh))
2285 {
2286 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2287 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2288 return -1;
2289 }
2290
2291 /* Check network mask, Silently discarded. */
2292 if (! ospf_check_network_mask (oi, iph->ip_src))
2293 {
2294 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2295 IF_NAME (oi), inet_ntoa (iph->ip_src));
2296 return -1;
2297 }
2298
2299 /* Check authentication. */
2300 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2301 {
2302 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2303 IF_NAME (oi));
2304 return -1;
2305 }
2306
2307 if (! ospf_check_auth (oi, ibuf, ospfh))
2308 {
2309 zlog_warn ("interface %s: ospf_read authentication failed.",
2310 IF_NAME (oi));
2311 return -1;
2312 }
2313
2314 /* if check sum is invalid, packet is discarded. */
2315 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2316 {
2317 if (! ospf_check_sum (ospfh))
2318 {
2319 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2320 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2321 return -1;
2322 }
2323 }
2324 else
2325 {
2326 if (ospfh->checksum != 0)
2327 return -1;
2328 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2329 {
2330 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2331 IF_NAME (oi));
2332 return -1;
2333 }
2334 }
2335
2336 return 0;
2337}
2338
2339/* Starting point of packet process function. */
2340int
2341ospf_read (struct thread *thread)
2342{
2343 int ret;
2344 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002345 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002346 struct ospf_interface *oi;
2347 struct ip *iph;
2348 struct ospf_header *ospfh;
2349 u_int16_t length;
2350 struct interface *ifp;
2351
2352 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002353 ospf = THREAD_ARG (thread);
2354 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002355
2356 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002357 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002358 if (ibuf == NULL)
2359 return -1;
2360
paul06f953f2004-10-22 17:00:38 +00002361 iph = (struct ip *) STREAM_DATA (ibuf);
2362 sockopt_iphdrincl_swab_systoh (iph);
2363
paulac191232004-10-22 12:05:17 +00002364 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002365 /* Handle cases where the platform does not support retrieving the ifindex,
2366 and also platforms (such as Solaris 8) that claim to support ifindex
2367 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002368 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002369
pauld3f0d622004-05-05 15:27:15 +00002370 if (ifp == NULL)
2371 {
2372 stream_free (ibuf);
2373 return 0;
2374 }
paul6b333612004-10-11 10:11:25 +00002375
paul718e3742002-12-13 20:15:29 +00002376 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002377 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002378
2379 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002380 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002381 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002382
paul718e3742002-12-13 20:15:29 +00002383 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002384 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002385 {
pauld3241812003-09-29 12:42:39 +00002386 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2387 {
ajs2a42e282004-12-08 18:43:03 +00002388 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002389 inet_ntoa (iph->ip_src));
2390 }
paul718e3742002-12-13 20:15:29 +00002391 stream_free (ibuf);
2392 return 0;
2393 }
2394
2395 /* Adjust size to message length. */
2396 stream_forward (ibuf, iph->ip_hl * 4);
2397
2398 /* Get ospf packet header. */
2399 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2400
2401 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002402 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002403
2404 /* if no local ospf_interface,
2405 * or header area is backbone but ospf_interface is not
2406 * check for VLINK interface
2407 */
2408 if ( (oi == NULL) ||
2409 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2410 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2411 )
2412 {
2413 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2414 {
2415 zlog_warn ("Packet from [%s] received on link %s"
2416 " but no ospf_interface",
2417 inet_ntoa (iph->ip_src), ifp->name);
2418 stream_free (ibuf);
2419 return 0;
2420 }
2421 }
2422
2423 /* else it must be a local ospf interface, check it was received on
2424 * correct link
2425 */
2426 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002427 {
2428 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002429 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002430 stream_free (ibuf);
2431 return 0;
2432 }
ajsc3eab872005-01-29 15:52:07 +00002433 else if (oi->state == ISM_InterfaceDown)
2434 {
2435 zlog_warn ("Ignoring packet from [%s] received on interface that is "
2436 "down [%s]",
2437 inet_ntoa (iph->ip_src), ifp->name);
2438 stream_free (ibuf);
2439 return 0;
2440 }
paul718e3742002-12-13 20:15:29 +00002441
2442 /*
2443 * If the received packet is destined for AllDRouters, the packet
2444 * should be accepted only if the received ospf interface state is
2445 * either DR or Backup -- endo.
2446 */
2447 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2448 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2449 {
2450 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2451 inet_ntoa (iph->ip_src), IF_NAME (oi),
2452 LOOKUP (ospf_ism_state_msg, oi->state));
2453 stream_free (ibuf);
2454 return 0;
2455 }
2456
2457 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002458 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2459 {
paul718e3742002-12-13 20:15:29 +00002460 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002461 {
ajs2a42e282004-12-08 18:43:03 +00002462 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002463 ospf_packet_dump (ibuf);
2464 }
paul718e3742002-12-13 20:15:29 +00002465
ajs2a42e282004-12-08 18:43:03 +00002466 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002467 ospf_packet_type_str[ospfh->type],
2468 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002469 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2470 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002471
2472 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002473 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002474 }
paul718e3742002-12-13 20:15:29 +00002475
2476 /* Some header verification. */
2477 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2478 if (ret < 0)
2479 {
pauld3241812003-09-29 12:42:39 +00002480 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2481 {
ajs2a42e282004-12-08 18:43:03 +00002482 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002483 "dropping.",
2484 ospf_packet_type_str[ospfh->type],
2485 inet_ntoa (iph->ip_src));
2486 }
paul718e3742002-12-13 20:15:29 +00002487 stream_free (ibuf);
2488 return ret;
2489 }
2490
2491 stream_forward (ibuf, OSPF_HEADER_SIZE);
2492
2493 /* Adjust size to message length. */
2494 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2495
2496 /* Read rest of the packet and call each sort of packet routine. */
2497 switch (ospfh->type)
2498 {
2499 case OSPF_MSG_HELLO:
2500 ospf_hello (iph, ospfh, ibuf, oi, length);
2501 break;
2502 case OSPF_MSG_DB_DESC:
2503 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2504 break;
2505 case OSPF_MSG_LS_REQ:
2506 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2507 break;
2508 case OSPF_MSG_LS_UPD:
2509 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2510 break;
2511 case OSPF_MSG_LS_ACK:
2512 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2513 break;
2514 default:
2515 zlog (NULL, LOG_WARNING,
2516 "interface %s: OSPF packet header type %d is illegal",
2517 IF_NAME (oi), ospfh->type);
2518 break;
2519 }
2520
2521 stream_free (ibuf);
2522 return 0;
2523}
2524
2525/* Make OSPF header. */
2526void
2527ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2528{
2529 struct ospf_header *ospfh;
2530
2531 ospfh = (struct ospf_header *) STREAM_DATA (s);
2532
2533 ospfh->version = (u_char) OSPF_VERSION;
2534 ospfh->type = (u_char) type;
2535
paul68980082003-03-25 05:07:42 +00002536 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002537
2538 ospfh->checksum = 0;
2539 ospfh->area_id = oi->area->area_id;
2540 ospfh->auth_type = htons (ospf_auth_type (oi));
2541
2542 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2543
2544 ospf_output_forward (s, OSPF_HEADER_SIZE);
2545}
2546
2547/* Make Authentication Data. */
2548int
2549ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2550{
2551 struct crypt_key *ck;
2552
2553 switch (ospf_auth_type (oi))
2554 {
2555 case OSPF_AUTH_NULL:
2556 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2557 break;
2558 case OSPF_AUTH_SIMPLE:
2559 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2560 OSPF_AUTH_SIMPLE_SIZE);
2561 break;
2562 case OSPF_AUTH_CRYPTOGRAPHIC:
2563 /* If key is not set, then set 0. */
2564 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2565 {
2566 ospfh->u.crypt.zero = 0;
2567 ospfh->u.crypt.key_id = 0;
2568 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2569 }
2570 else
2571 {
2572 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2573 ospfh->u.crypt.zero = 0;
2574 ospfh->u.crypt.key_id = ck->key_id;
2575 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2576 }
2577 /* note: the seq is done in ospf_make_md5_digest() */
2578 break;
2579 default:
2580 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2581 break;
2582 }
2583
2584 return 0;
2585}
2586
2587/* Fill rest of OSPF header. */
2588void
2589ospf_fill_header (struct ospf_interface *oi,
2590 struct stream *s, u_int16_t length)
2591{
2592 struct ospf_header *ospfh;
2593
2594 ospfh = (struct ospf_header *) STREAM_DATA (s);
2595
2596 /* Fill length. */
2597 ospfh->length = htons (length);
2598
2599 /* Calculate checksum. */
2600 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2601 ospfh->checksum = in_cksum (ospfh, length);
2602 else
2603 ospfh->checksum = 0;
2604
2605 /* Add Authentication Data. */
2606 ospf_make_auth (oi, ospfh);
2607}
2608
2609int
2610ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2611{
2612 struct ospf_neighbor *nbr;
2613 struct route_node *rn;
2614 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2615 struct in_addr mask;
2616 unsigned long p;
2617 int flag = 0;
2618
2619 /* Set netmask of interface. */
2620 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2621 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2622 masklen2ip (oi->address->prefixlen, &mask);
2623 else
2624 memset ((char *) &mask, 0, sizeof (struct in_addr));
2625 stream_put_ipv4 (s, mask.s_addr);
2626
2627 /* Set Hello Interval. */
2628 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2629
2630 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002631 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002632 OPTIONS(oi), IF_NAME (oi));
2633
2634 /* Set Options. */
2635 stream_putc (s, OPTIONS (oi));
2636
2637 /* Set Router Priority. */
2638 stream_putc (s, PRIORITY (oi));
2639
2640 /* Set Router Dead Interval. */
2641 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2642
2643 /* Set Designated Router. */
2644 stream_put_ipv4 (s, DR (oi).s_addr);
2645
2646 p = s->putp;
2647
2648 /* Set Backup Designated Router. */
2649 stream_put_ipv4 (s, BDR (oi).s_addr);
2650
2651 /* Add neighbor seen. */
2652 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002653 if ((nbr = rn->info))
2654 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2655 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2656 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2657 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002658 {
2659 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002660 if (nbr->d_router.s_addr != 0
2661 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2662 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2663 flag = 1;
paul718e3742002-12-13 20:15:29 +00002664
2665 stream_put_ipv4 (s, nbr->router_id.s_addr);
2666 length += 4;
2667 }
2668
2669 /* Let neighbor generate BackupSeen. */
2670 if (flag == 1)
2671 {
2672 stream_set_putp (s, p);
2673 stream_put_ipv4 (s, 0);
2674 }
2675
2676 return length;
2677}
2678
2679int
2680ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2681 struct stream *s)
2682{
2683 struct ospf_lsa *lsa;
2684 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2685 u_char options;
2686 unsigned long pp;
2687 int i;
2688 struct ospf_lsdb *lsdb;
2689
2690 /* Set Interface MTU. */
2691 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2692 stream_putw (s, 0);
2693 else
2694 stream_putw (s, oi->ifp->mtu);
2695
2696 /* Set Options. */
2697 options = OPTIONS (oi);
2698#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002699 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002700 {
2701 if (IS_SET_DD_I (nbr->dd_flags)
2702 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2703 /*
2704 * Set O-bit in the outgoing DD packet for capablity negotiation,
2705 * if one of following case is applicable.
2706 *
2707 * 1) WaitTimer expiration event triggered the neighbor state to
2708 * change to Exstart, but no (valid) DD packet has received
2709 * from the neighbor yet.
2710 *
2711 * 2) At least one DD packet with O-bit on has received from the
2712 * neighbor.
2713 */
2714 SET_FLAG (options, OSPF_OPTION_O);
2715 }
2716#endif /* HAVE_OPAQUE_LSA */
2717 stream_putc (s, options);
2718
2719 /* Keep pointer to flags. */
2720 pp = stream_get_putp (s);
2721 stream_putc (s, nbr->dd_flags);
2722
2723 /* Set DD Sequence Number. */
2724 stream_putl (s, nbr->dd_seqnum);
2725
2726 if (ospf_db_summary_isempty (nbr))
2727 {
2728 if (nbr->state >= NSM_Exchange)
2729 {
2730 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2731 /* Set DD flags again */
2732 stream_set_putp (s, pp);
2733 stream_putc (s, nbr->dd_flags);
2734 }
2735 return length;
2736 }
2737
2738 /* Describe LSA Header from Database Summary List. */
2739 lsdb = &nbr->db_sum;
2740
2741 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2742 {
2743 struct route_table *table = lsdb->type[i].db;
2744 struct route_node *rn;
2745
2746 for (rn = route_top (table); rn; rn = route_next (rn))
2747 if ((lsa = rn->info) != NULL)
2748 {
2749#ifdef HAVE_OPAQUE_LSA
2750 if (IS_OPAQUE_LSA (lsa->data->type)
2751 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2752 {
2753 /* Suppress advertising opaque-informations. */
2754 /* Remove LSA from DB summary list. */
2755 ospf_lsdb_delete (lsdb, lsa);
2756 continue;
2757 }
2758#endif /* HAVE_OPAQUE_LSA */
2759
2760 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2761 {
2762 struct lsa_header *lsah;
2763 u_int16_t ls_age;
2764
2765 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002766 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002767 break;
2768
2769 /* Keep pointer to LS age. */
2770 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2771 stream_get_putp (s));
2772
2773 /* Proceed stream pointer. */
2774 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2775 length += OSPF_LSA_HEADER_SIZE;
2776
2777 /* Set LS age. */
2778 ls_age = LS_AGE (lsa);
2779 lsah->ls_age = htons (ls_age);
2780
2781 }
2782
2783 /* Remove LSA from DB summary list. */
2784 ospf_lsdb_delete (lsdb, lsa);
2785 }
2786 }
2787
2788 return length;
2789}
2790
2791int
2792ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2793 unsigned long delta, struct ospf_neighbor *nbr,
2794 struct ospf_lsa *lsa)
2795{
2796 struct ospf_interface *oi;
2797
2798 oi = nbr->oi;
2799
2800 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002801 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002802 return 0;
2803
2804 stream_putl (s, lsa->data->type);
2805 stream_put_ipv4 (s, lsa->data->id.s_addr);
2806 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2807
2808 ospf_lsa_unlock (nbr->ls_req_last);
2809 nbr->ls_req_last = ospf_lsa_lock (lsa);
2810
2811 *length += 12;
2812 return 1;
2813}
2814
2815int
2816ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2817{
2818 struct ospf_lsa *lsa;
2819 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2820 unsigned long delta = stream_get_putp(s)+12;
2821 struct route_table *table;
2822 struct route_node *rn;
2823 int i;
2824 struct ospf_lsdb *lsdb;
2825
2826 lsdb = &nbr->ls_req;
2827
2828 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2829 {
2830 table = lsdb->type[i].db;
2831 for (rn = route_top (table); rn; rn = route_next (rn))
2832 if ((lsa = (rn->info)) != NULL)
2833 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2834 {
2835 route_unlock_node (rn);
2836 break;
2837 }
2838 }
2839 return length;
2840}
2841
2842int
2843ls_age_increment (struct ospf_lsa *lsa, int delay)
2844{
2845 int age;
2846
2847 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2848
2849 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2850}
2851
2852int
hasso52dc7ee2004-09-23 19:18:23 +00002853ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002854{
2855 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002856 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002857 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002858 unsigned int size_noauth;
paul718e3742002-12-13 20:15:29 +00002859 unsigned long delta = stream_get_putp (s);
2860 unsigned long pp;
2861 int count = 0;
2862
2863 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002864 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002865
paul718e3742002-12-13 20:15:29 +00002866 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002867 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002868
gdt86f1fd92005-01-10 14:20:43 +00002869 /* Calculate amount of packet usable for data. */
2870 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2871
paul718e3742002-12-13 20:15:29 +00002872 while ((node = listhead (update)) != NULL)
2873 {
2874 struct lsa_header *lsah;
2875 u_int16_t ls_age;
2876
2877 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002878 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002879
2880 lsa = getdata (node);
2881 assert (lsa);
2882 assert (lsa->data);
2883
paul68b73392004-09-12 14:21:37 +00002884 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002885 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002886 break;
2887
paul718e3742002-12-13 20:15:29 +00002888 /* Keep pointer to LS age. */
2889 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2890
2891 /* Put LSA to Link State Request. */
2892 stream_put (s, lsa->data, ntohs (lsa->data->length));
2893
2894 /* Set LS age. */
2895 /* each hop must increment an lsa_age by transmit_delay
2896 of OSPF interface */
2897 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2898 lsah->ls_age = htons (ls_age);
2899
2900 length += ntohs (lsa->data->length);
2901 count++;
2902
2903 list_delete_node (update, node);
2904 ospf_lsa_unlock (lsa);
2905 }
2906
2907 /* Now set #LSAs. */
2908 stream_set_putp (s, pp);
2909 stream_putl (s, count);
2910
2911 stream_set_putp (s, s->endp);
2912
2913 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002914 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002915 return length;
2916}
2917
2918int
hasso52dc7ee2004-09-23 19:18:23 +00002919ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002920{
hasso52dc7ee2004-09-23 19:18:23 +00002921 struct list *rm_list;
2922 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002923 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2924 unsigned long delta = stream_get_putp(s) + 24;
2925 struct ospf_lsa *lsa;
2926
2927 rm_list = list_new ();
2928
2929 for (node = listhead (ack); node; nextnode (node))
2930 {
2931 lsa = getdata (node);
2932 assert (lsa);
2933
gdt86f1fd92005-01-10 14:20:43 +00002934 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002935 break;
2936
2937 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2938 length += OSPF_LSA_HEADER_SIZE;
2939
2940 listnode_add (rm_list, lsa);
2941 }
2942
2943 /* Remove LSA from LS-Ack list. */
2944 for (node = listhead (rm_list); node; nextnode (node))
2945 {
2946 lsa = (struct ospf_lsa *) getdata (node);
2947
2948 listnode_delete (ack, lsa);
2949 ospf_lsa_unlock (lsa);
2950 }
2951
2952 list_delete (rm_list);
2953
2954 return length;
2955}
2956
2957void
2958ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2959{
2960 struct ospf_packet *op;
2961 u_int16_t length = OSPF_HEADER_SIZE;
2962
2963 op = ospf_packet_new (oi->ifp->mtu);
2964
2965 /* Prepare OSPF common header. */
2966 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2967
2968 /* Prepare OSPF Hello body. */
2969 length += ospf_make_hello (oi, op->s);
2970
2971 /* Fill OSPF header. */
2972 ospf_fill_header (oi, op->s, length);
2973
2974 /* Set packet length. */
2975 op->length = length;
2976
2977 op->dst.s_addr = addr->s_addr;
2978
2979 /* Add packet to the interface output queue. */
2980 ospf_packet_add (oi, op);
2981
2982 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002983 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002984}
2985
2986void
2987ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2988{
2989 struct ospf_interface *oi;
2990
2991 oi = nbr_nbma->oi;
2992 assert(oi);
2993
2994 /* If this is passive interface, do not send OSPF Hello. */
2995 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2996 return;
2997
2998 if (oi->type != OSPF_IFTYPE_NBMA)
2999 return;
3000
3001 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3002 return;
3003
3004 if (PRIORITY(oi) == 0)
3005 return;
3006
3007 if (nbr_nbma->priority == 0
3008 && oi->state != ISM_DR && oi->state != ISM_Backup)
3009 return;
3010
3011 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3012}
3013
3014int
3015ospf_poll_timer (struct thread *thread)
3016{
3017 struct ospf_nbr_nbma *nbr_nbma;
3018
3019 nbr_nbma = THREAD_ARG (thread);
3020 nbr_nbma->t_poll = NULL;
3021
3022 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003023 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003024 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3025
3026 ospf_poll_send (nbr_nbma);
3027
3028 if (nbr_nbma->v_poll > 0)
3029 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3030 nbr_nbma->v_poll);
3031
3032 return 0;
3033}
3034
3035
3036int
3037ospf_hello_reply_timer (struct thread *thread)
3038{
3039 struct ospf_neighbor *nbr;
3040
3041 nbr = THREAD_ARG (thread);
3042 nbr->t_hello_reply = NULL;
3043
3044 assert (nbr->oi);
3045
3046 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003047 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003048 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3049
3050 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3051
3052 return 0;
3053}
3054
3055/* Send OSPF Hello. */
3056void
3057ospf_hello_send (struct ospf_interface *oi)
3058{
3059 struct ospf_packet *op;
3060 u_int16_t length = OSPF_HEADER_SIZE;
3061
3062 /* If this is passive interface, do not send OSPF Hello. */
3063 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3064 return;
3065
3066 op = ospf_packet_new (oi->ifp->mtu);
3067
3068 /* Prepare OSPF common header. */
3069 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3070
3071 /* Prepare OSPF Hello body. */
3072 length += ospf_make_hello (oi, op->s);
3073
3074 /* Fill OSPF header. */
3075 ospf_fill_header (oi, op->s, length);
3076
3077 /* Set packet length. */
3078 op->length = length;
3079
3080 if (oi->type == OSPF_IFTYPE_NBMA)
3081 {
3082 struct ospf_neighbor *nbr;
3083 struct route_node *rn;
3084
3085 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3086 if ((nbr = rn->info))
3087 if (nbr != oi->nbr_self)
3088 if (nbr->state != NSM_Down)
3089 {
3090 /* RFC 2328 Section 9.5.1
3091 If the router is not eligible to become Designated Router,
3092 it must periodically send Hello Packets to both the
3093 Designated Router and the Backup Designated Router (if they
3094 exist). */
3095 if (PRIORITY(oi) == 0 &&
3096 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3097 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3098 continue;
3099
3100 /* If the router is eligible to become Designated Router, it
3101 must periodically send Hello Packets to all neighbors that
3102 are also eligible. In addition, if the router is itself the
3103 Designated Router or Backup Designated Router, it must also
3104 send periodic Hello Packets to all other neighbors. */
3105
3106 if (nbr->priority == 0 && oi->state == ISM_DROther)
3107 continue;
3108 /* if oi->state == Waiting, send hello to all neighbors */
3109 {
3110 struct ospf_packet *op_dup;
3111
3112 op_dup = ospf_packet_dup(op);
3113 op_dup->dst = nbr->address.u.prefix4;
3114
3115 /* Add packet to the interface output queue. */
3116 ospf_packet_add (oi, op_dup);
3117
paul020709f2003-04-04 02:44:16 +00003118 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003119 }
3120
3121 }
3122 ospf_packet_free (op);
3123 }
3124 else
3125 {
3126 /* Decide destination address. */
3127 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3128 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3129 else
3130 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3131
3132 /* Add packet to the interface output queue. */
3133 ospf_packet_add (oi, op);
3134
3135 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003136 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003137 }
3138}
3139
3140/* Send OSPF Database Description. */
3141void
3142ospf_db_desc_send (struct ospf_neighbor *nbr)
3143{
3144 struct ospf_interface *oi;
3145 struct ospf_packet *op;
3146 u_int16_t length = OSPF_HEADER_SIZE;
3147
3148 oi = nbr->oi;
3149 op = ospf_packet_new (oi->ifp->mtu);
3150
3151 /* Prepare OSPF common header. */
3152 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3153
3154 /* Prepare OSPF Database Description body. */
3155 length += ospf_make_db_desc (oi, nbr, op->s);
3156
3157 /* Fill OSPF header. */
3158 ospf_fill_header (oi, op->s, length);
3159
3160 /* Set packet length. */
3161 op->length = length;
3162
3163 /* Decide destination address. */
3164 op->dst = nbr->address.u.prefix4;
3165
3166 /* Add packet to the interface output queue. */
3167 ospf_packet_add (oi, op);
3168
3169 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003170 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003171
3172 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3173 if (nbr->last_send)
3174 ospf_packet_free (nbr->last_send);
3175 nbr->last_send = ospf_packet_dup (op);
3176 gettimeofday (&nbr->last_send_ts, NULL);
3177}
3178
3179/* Re-send Database Description. */
3180void
3181ospf_db_desc_resend (struct ospf_neighbor *nbr)
3182{
3183 struct ospf_interface *oi;
3184
3185 oi = nbr->oi;
3186
3187 /* Add packet to the interface output queue. */
3188 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3189
3190 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003191 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003192}
3193
3194/* Send Link State Request. */
3195void
3196ospf_ls_req_send (struct ospf_neighbor *nbr)
3197{
3198 struct ospf_interface *oi;
3199 struct ospf_packet *op;
3200 u_int16_t length = OSPF_HEADER_SIZE;
3201
3202 oi = nbr->oi;
3203 op = ospf_packet_new (oi->ifp->mtu);
3204
3205 /* Prepare OSPF common header. */
3206 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3207
3208 /* Prepare OSPF Link State Request body. */
3209 length += ospf_make_ls_req (nbr, op->s);
3210 if (length == OSPF_HEADER_SIZE)
3211 {
3212 ospf_packet_free (op);
3213 return;
3214 }
3215
3216 /* Fill OSPF header. */
3217 ospf_fill_header (oi, op->s, length);
3218
3219 /* Set packet length. */
3220 op->length = length;
3221
3222 /* Decide destination address. */
3223 op->dst = nbr->address.u.prefix4;
3224
3225 /* Add packet to the interface output queue. */
3226 ospf_packet_add (oi, op);
3227
3228 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003229 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003230
3231 /* Add Link State Request Retransmission Timer. */
3232 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3233}
3234
3235/* Send Link State Update with an LSA. */
3236void
3237ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3238 int flag)
3239{
hasso52dc7ee2004-09-23 19:18:23 +00003240 struct list *update;
paul718e3742002-12-13 20:15:29 +00003241
3242 update = list_new ();
3243
3244 listnode_add (update, lsa);
3245 ospf_ls_upd_send (nbr, update, flag);
3246
3247 list_delete (update);
3248}
3249
paul68b73392004-09-12 14:21:37 +00003250/* Determine size for packet. Must be at least big enough to accomodate next
3251 * LSA on list, which may be bigger than MTU size.
3252 *
3253 * Return pointer to new ospf_packet
3254 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3255 * on packet sizes (in which case offending LSA is deleted from update list)
3256 */
3257static struct ospf_packet *
3258ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3259{
3260 struct ospf_lsa *lsa;
3261 struct listnode *ln;
3262 size_t size;
3263 static char warned = 0;
3264
3265 ln = listhead (update);
3266 lsa = getdata (ln);
3267 assert (lsa);
3268 assert (lsa->data);
3269
3270 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3271 > ospf_packet_max (oi))
3272 {
3273 if (!warned)
3274 {
3275 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3276 "will need to fragment. Not optimal. Try divide up"
3277 " your network with areas. Use 'debug ospf packet send'"
3278 " to see details, or look at 'show ip ospf database ..'");
3279 warned = 1;
3280 }
3281
3282 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003283 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003284 " %d bytes originated by %s, will be fragmented!",
3285 inet_ntoa (lsa->data->id),
3286 ntohs (lsa->data->length),
3287 inet_ntoa (lsa->data->adv_router));
3288
3289 /*
3290 * Allocate just enough to fit this LSA only, to avoid including other
3291 * LSAs in fragmented LSA Updates.
3292 */
3293 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3294 + OSPF_LS_UPD_MIN_SIZE;
3295 }
3296 else
3297 size = oi->ifp->mtu;
3298
gdt86f1fd92005-01-10 14:20:43 +00003299 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003300 if (size > OSPF_MAX_PACKET_SIZE)
3301 {
3302 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003303 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003304 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003305 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003306 (long int) size);
paul68b73392004-09-12 14:21:37 +00003307 list_delete_node (update, ln);
3308 return NULL;
3309 }
3310
3311 return ospf_packet_new (size);
3312}
3313
paul718e3742002-12-13 20:15:29 +00003314static void
hasso52dc7ee2004-09-23 19:18:23 +00003315ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003316 struct in_addr addr)
3317{
3318 struct ospf_packet *op;
3319 u_int16_t length = OSPF_HEADER_SIZE;
3320
3321 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003322 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003323
3324 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003325
3326 /* Prepare OSPF common header. */
3327 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3328
paul59ea14c2004-07-14 20:50:36 +00003329 /* Prepare OSPF Link State Update body.
3330 * Includes Type-7 translation.
3331 */
paul718e3742002-12-13 20:15:29 +00003332 length += ospf_make_ls_upd (oi, update, op->s);
3333
3334 /* Fill OSPF header. */
3335 ospf_fill_header (oi, op->s, length);
3336
3337 /* Set packet length. */
3338 op->length = length;
3339
3340 /* Decide destination address. */
3341 op->dst.s_addr = addr.s_addr;
3342
3343 /* Add packet to the interface output queue. */
3344 ospf_packet_add (oi, op);
3345
3346 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003347 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003348}
3349
3350static int
3351ospf_ls_upd_send_queue_event (struct thread *thread)
3352{
3353 struct ospf_interface *oi = THREAD_ARG(thread);
3354 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003355 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003356 struct list *update;
paul68b73392004-09-12 14:21:37 +00003357 char again = 0;
paul718e3742002-12-13 20:15:29 +00003358
3359 oi->t_ls_upd_event = NULL;
3360
3361 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003362 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003363
paul736d3442003-07-24 23:22:57 +00003364 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003365 {
paul736d3442003-07-24 23:22:57 +00003366 rnext = route_next (rn);
3367
paul718e3742002-12-13 20:15:29 +00003368 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003369 continue;
paul68b73392004-09-12 14:21:37 +00003370
3371 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003372
paul48fe13b2004-07-27 17:40:44 +00003373 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003374
paul68b73392004-09-12 14:21:37 +00003375 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003376 if (listcount(update) == 0)
3377 {
3378 list_delete (rn->info);
3379 rn->info = NULL;
3380 route_unlock_node (rn);
3381 }
3382 else
paul68b73392004-09-12 14:21:37 +00003383 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003384 }
3385
3386 if (again != 0)
3387 {
3388 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003389 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003390 " %d nodes to try again, raising new event", again);
3391 oi->t_ls_upd_event =
3392 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003393 }
3394
3395 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003396 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003397
paul718e3742002-12-13 20:15:29 +00003398 return 0;
3399}
3400
3401void
hasso52dc7ee2004-09-23 19:18:23 +00003402ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003403{
3404 struct ospf_interface *oi;
3405 struct prefix_ipv4 p;
3406 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003407 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003408
3409 oi = nbr->oi;
3410
3411 p.family = AF_INET;
3412 p.prefixlen = IPV4_MAX_BITLEN;
3413
3414 /* Decide destination address. */
3415 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3416 p.prefix = oi->vl_data->peer_addr;
3417 else if (flag == OSPF_SEND_PACKET_DIRECT)
3418 p.prefix = nbr->address.u.prefix4;
3419 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3420 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3421 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3422 && (flag == OSPF_SEND_PACKET_INDIRECT))
3423 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003424 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3425 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003426 else
3427 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3428
3429 if (oi->type == OSPF_IFTYPE_NBMA)
3430 {
3431 if (flag == OSPF_SEND_PACKET_INDIRECT)
3432 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3433 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3434 zlog_warn ("* LS-Update is sent to myself.");
3435 }
3436
3437 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3438
3439 if (rn->info == NULL)
3440 rn->info = list_new ();
3441
3442 for (n = listhead (update); n; nextnode (n))
3443 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3444
3445 if (oi->t_ls_upd_event == NULL)
3446 oi->t_ls_upd_event =
3447 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3448}
3449
3450static void
hasso52dc7ee2004-09-23 19:18:23 +00003451ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3452 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003453{
3454 struct ospf_packet *op;
3455 u_int16_t length = OSPF_HEADER_SIZE;
3456
3457 op = ospf_packet_new (oi->ifp->mtu);
3458
3459 /* Prepare OSPF common header. */
3460 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3461
3462 /* Prepare OSPF Link State Acknowledgment body. */
3463 length += ospf_make_ls_ack (oi, ack, op->s);
3464
3465 /* Fill OSPF header. */
3466 ospf_fill_header (oi, op->s, length);
3467
3468 /* Set packet length. */
3469 op->length = length;
3470
3471 /* Set destination IP address. */
3472 op->dst = dst;
3473
3474 /* Add packet to the interface output queue. */
3475 ospf_packet_add (oi, op);
3476
3477 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003478 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003479}
3480
3481static int
3482ospf_ls_ack_send_event (struct thread *thread)
3483{
3484 struct ospf_interface *oi = THREAD_ARG (thread);
3485
3486 oi->t_ls_ack_direct = NULL;
3487
3488 while (listcount (oi->ls_ack_direct.ls_ack))
3489 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3490 oi->ls_ack_direct.dst);
3491
3492 return 0;
3493}
3494
3495void
3496ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3497{
3498 struct ospf_interface *oi = nbr->oi;
3499
3500 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3501 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3502
3503 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3504
3505 if (oi->t_ls_ack_direct == NULL)
3506 oi->t_ls_ack_direct =
3507 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3508}
3509
3510/* Send Link State Acknowledgment delayed. */
3511void
3512ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3513{
3514 struct in_addr dst;
3515
3516 /* Decide destination address. */
3517 /* RFC2328 Section 13.5 On non-broadcast
3518 networks, delayed Link State Acknowledgment packets must be
3519 unicast separately over each adjacency (i.e., neighbor whose
3520 state is >= Exchange). */
3521 if (oi->type == OSPF_IFTYPE_NBMA)
3522 {
3523 struct ospf_neighbor *nbr;
3524 struct route_node *rn;
3525
3526 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3527 if ((nbr = rn->info) != NULL)
3528 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3529 while (listcount (oi->ls_ack))
3530 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3531 return;
3532 }
3533 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3534 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3535 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3536 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3537 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3538 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003539 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3540 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003541 else
3542 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3543
3544 while (listcount (oi->ls_ack))
3545 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3546}