blob: 4f18c04d3e089ed0990ab45ac6ecbe83244675f1 [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
paul718e3742002-12-13 20:15:29 +000087struct ospf_packet *
88ospf_packet_new (size_t size)
89{
90 struct ospf_packet *new;
91
92 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
93 new->s = stream_new (size);
94
95 return new;
96}
97
98void
99ospf_packet_free (struct ospf_packet *op)
100{
101 if (op->s)
102 stream_free (op->s);
103
104 XFREE (MTYPE_OSPF_PACKET, op);
105
106 op = NULL;
107}
108
109struct ospf_fifo *
110ospf_fifo_new ()
111{
112 struct ospf_fifo *new;
113
114 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
115 return new;
116}
117
118/* Add new packet to fifo. */
119void
120ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
121{
122 if (fifo->tail)
123 fifo->tail->next = op;
124 else
125 fifo->head = op;
126
127 fifo->tail = op;
128
129 fifo->count++;
130}
131
132/* Delete first packet from fifo. */
133struct ospf_packet *
134ospf_fifo_pop (struct ospf_fifo *fifo)
135{
136 struct ospf_packet *op;
137
138 op = fifo->head;
139
140 if (op)
141 {
142 fifo->head = op->next;
143
144 if (fifo->head == NULL)
145 fifo->tail = NULL;
146
147 fifo->count--;
148 }
149
150 return op;
151}
152
153/* Return first fifo entry. */
154struct ospf_packet *
155ospf_fifo_head (struct ospf_fifo *fifo)
156{
157 return fifo->head;
158}
159
160/* Flush ospf packet fifo. */
161void
162ospf_fifo_flush (struct ospf_fifo *fifo)
163{
164 struct ospf_packet *op;
165 struct ospf_packet *next;
166
167 for (op = fifo->head; op; op = next)
168 {
169 next = op->next;
170 ospf_packet_free (op);
171 }
172 fifo->head = fifo->tail = NULL;
173 fifo->count = 0;
174}
175
176/* Free ospf packet fifo. */
177void
178ospf_fifo_free (struct ospf_fifo *fifo)
179{
180 ospf_fifo_flush (fifo);
181
182 XFREE (MTYPE_OSPF_FIFO, fifo);
183}
184
185void
186ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
187{
ajsc3eab872005-01-29 15:52:07 +0000188 if (!oi->obuf)
189 {
190 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
191 "destination %s) called with NULL obuf, ignoring "
192 "(please report this bug)!\n",
193 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
194 ospf_packet_type_str[stream_getc_from(op->s, 1)],
195 inet_ntoa (op->dst));
196 return;
197 }
198
paul718e3742002-12-13 20:15:29 +0000199 /* Add packet to end of queue. */
200 ospf_fifo_push (oi->obuf, op);
201
202 /* Debug of packet fifo*/
203 /* ospf_fifo_debug (oi->obuf); */
204}
205
206void
207ospf_packet_delete (struct ospf_interface *oi)
208{
209 struct ospf_packet *op;
210
211 op = ospf_fifo_pop (oi->obuf);
212
213 if (op)
214 ospf_packet_free (op);
215}
216
paul718e3742002-12-13 20:15:29 +0000217struct ospf_packet *
218ospf_packet_dup (struct ospf_packet *op)
219{
220 struct ospf_packet *new;
221
paul37163d62003-02-03 18:40:56 +0000222 if (stream_get_endp(op->s) != op->length)
223 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000224 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000225
226 /* Reserve space for MD5 authentication that may be added later. */
227 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000228 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000229
230 new->dst = op->dst;
231 new->length = op->length;
232
233 return new;
234}
235
gdt86f1fd92005-01-10 14:20:43 +0000236/* XXX inline */
237unsigned int
238ospf_packet_authspace (struct ospf_interface *oi)
239{
240 int auth = 0;
241
242 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
243 auth = OSPF_AUTH_MD5_SIZE;
244
245 return auth;
246}
247
paul6c835672004-10-11 11:00:30 +0000248unsigned int
paul718e3742002-12-13 20:15:29 +0000249ospf_packet_max (struct ospf_interface *oi)
250{
251 int max;
252
gdt86f1fd92005-01-10 14:20:43 +0000253 max = oi->ifp->mtu - ospf_packet_authspace(oi);
254
paul68b73392004-09-12 14:21:37 +0000255 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000256
257 return max;
258}
259
260
261int
262ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
263 u_int16_t length)
264{
paul6c835672004-10-11 11:00:30 +0000265 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000266 struct md5_ctx ctx;
267 unsigned char digest[OSPF_AUTH_MD5_SIZE];
268 unsigned char *pdigest;
269 struct crypt_key *ck;
270 struct ospf_header *ospfh;
271 struct ospf_neighbor *nbr;
272
273
274 ibuf = STREAM_PNT (s);
275 ospfh = (struct ospf_header *) ibuf;
276
277 /* Get pointer to the end of the packet. */
278 pdigest = ibuf + length;
279
280 /* Get secret key. */
281 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
282 ospfh->u.crypt.key_id);
283 if (ck == NULL)
284 {
285 zlog_warn ("interface %s: ospf_check_md5 no key %d",
286 IF_NAME (oi), ospfh->u.crypt.key_id);
287 return 0;
288 }
289
290 /* check crypto seqnum. */
291 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
292
293 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
294 {
295 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
296 IF_NAME (oi),
297 ntohl(ospfh->u.crypt.crypt_seqnum),
298 ntohl(nbr->crypt_seqnum));
299 return 0;
300 }
301
302 /* Generate a digest for the ospf packet - their digest + our digest. */
303 md5_init_ctx (&ctx);
304 md5_process_bytes (ibuf, length, &ctx);
305 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
306 md5_finish_ctx (&ctx, digest);
307
308 /* compare the two */
309 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
310 {
311 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
312 IF_NAME (oi));
313 return 0;
314 }
315
316 /* save neighbor's crypt_seqnum */
317 if (nbr)
318 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
319 return 1;
320}
321
322/* This function is called from ospf_write(), it will detect the
323 authentication scheme and if it is MD5, it will change the sequence
324 and update the MD5 digest. */
325int
326ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
327{
328 struct ospf_header *ospfh;
329 unsigned char digest[OSPF_AUTH_MD5_SIZE];
330 struct md5_ctx ctx;
331 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000332 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000333 struct crypt_key *ck;
334 char *auth_key;
335
336 ibuf = STREAM_DATA (op->s);
337 ospfh = (struct ospf_header *) ibuf;
338
339 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
340 return 0;
341
342 /* We do this here so when we dup a packet, we don't have to
343 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000344 t = (time(NULL) & 0xFFFFFFFF);
345 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
346 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000347
348 /* Get MD5 Authentication key from auth_key list. */
349 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000350 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000351 else
352 {
353 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000354 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000355 }
356
357 /* Generate a digest for the entire packet + our secret key. */
358 md5_init_ctx (&ctx);
359 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
360 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
361 md5_finish_ctx (&ctx, digest);
362
363 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000364 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000365
366 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000367 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
368
paul37163d62003-02-03 18:40:56 +0000369 if (stream_get_endp(op->s) != op->length)
370 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 +0000371
372 return OSPF_AUTH_MD5_SIZE;
373}
374
375
376int
377ospf_ls_req_timer (struct thread *thread)
378{
379 struct ospf_neighbor *nbr;
380
381 nbr = THREAD_ARG (thread);
382 nbr->t_ls_req = NULL;
383
384 /* Send Link State Request. */
385 if (ospf_ls_request_count (nbr))
386 ospf_ls_req_send (nbr);
387
388 /* Set Link State Request retransmission timer. */
389 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
390
391 return 0;
392}
393
394void
395ospf_ls_req_event (struct ospf_neighbor *nbr)
396{
397 if (nbr->t_ls_req)
398 {
399 thread_cancel (nbr->t_ls_req);
400 nbr->t_ls_req = NULL;
401 }
402 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
403}
404
405/* Cyclic timer function. Fist registered in ospf_nbr_new () in
406 ospf_neighbor.c */
407int
408ospf_ls_upd_timer (struct thread *thread)
409{
410 struct ospf_neighbor *nbr;
411
412 nbr = THREAD_ARG (thread);
413 nbr->t_ls_upd = NULL;
414
415 /* Send Link State Update. */
416 if (ospf_ls_retransmit_count (nbr) > 0)
417 {
hasso52dc7ee2004-09-23 19:18:23 +0000418 struct list *update;
paul718e3742002-12-13 20:15:29 +0000419 struct ospf_lsdb *lsdb;
420 int i;
421 struct timeval now;
422 int retransmit_interval;
423
424 gettimeofday (&now, NULL);
425 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
426
427 lsdb = &nbr->ls_rxmt;
428 update = list_new ();
429
430 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
431 {
432 struct route_table *table = lsdb->type[i].db;
433 struct route_node *rn;
434
435 for (rn = route_top (table); rn; rn = route_next (rn))
436 {
437 struct ospf_lsa *lsa;
438
439 if ((lsa = rn->info) != NULL)
440 /* Don't retransmit an LSA if we received it within
441 the last RxmtInterval seconds - this is to allow the
442 neighbour a chance to acknowledge the LSA as it may
443 have ben just received before the retransmit timer
444 fired. This is a small tweak to what is in the RFC,
445 but it will cut out out a lot of retransmit traffic
446 - MAG */
447 if (tv_cmp (tv_sub (now, lsa->tv_recv),
448 int2tv (retransmit_interval)) >= 0)
449 listnode_add (update, rn->info);
450 }
451 }
452
453 if (listcount (update) > 0)
454 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
455 list_delete (update);
456 }
457
458 /* Set LS Update retransmission timer. */
459 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
460
461 return 0;
462}
463
464int
465ospf_ls_ack_timer (struct thread *thread)
466{
467 struct ospf_interface *oi;
468
469 oi = THREAD_ARG (thread);
470 oi->t_ls_ack = NULL;
471
472 /* Send Link State Acknowledgment. */
473 if (listcount (oi->ls_ack) > 0)
474 ospf_ls_ack_send_delayed (oi);
475
476 /* Set LS Ack timer. */
477 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
478
479 return 0;
480}
481
paul0bfeca32004-09-24 08:07:54 +0000482#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000483static void
paul6a99f832004-09-27 12:56:30 +0000484ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000485 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000486 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000487{
488#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000489 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000490 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000491 int ret;
paul0bfeca32004-09-24 08:07:54 +0000492
493 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000494 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000495
496 /* we can but try.
497 *
498 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
499 * well as the IP_MF flag, making this all quite pointless.
500 *
501 * However, for a system on which IP_MF is left alone, and ip_id left
502 * alone or else which sets same ip_id for each fragment this might
503 * work, eg linux.
504 *
505 * XXX-TODO: It would be much nicer to have the kernel's use their
506 * existing fragmentation support to do this for us. Bugs/RFEs need to
507 * be raised against the various kernels.
508 */
509
510 /* set More Frag */
511 iph->ip_off |= IP_MF;
512
513 /* ip frag offset is expressed in units of 8byte words */
514 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
515
paul62d8e962004-11-02 20:26:45 +0000516 iovp = &msg->msg_iov[1];
517
paul0bfeca32004-09-24 08:07:54 +0000518 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
519 > maxdatasize )
520 {
521 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000522 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
523 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000524 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000525
paul18b12c32004-10-05 14:38:29 +0000526 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000527
paul6a99f832004-09-27 12:56:30 +0000528 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000529
paul18b12c32004-10-05 14:38:29 +0000530 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000531
532 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000533 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000534 " id %d, off %d, len %d, mtu %u failed with %s",
535 inet_ntoa (iph->ip_dst),
536 iph->ip_id,
537 iph->ip_off,
538 iph->ip_len,
539 mtu,
540 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000541
paul37ccfa32004-10-31 11:24:51 +0000542 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
543 {
ajs2a42e282004-12-08 18:43:03 +0000544 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000545 iph->ip_id, iph->ip_off, iph->ip_len,
546 inet_ntoa (iph->ip_dst));
547 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
548 {
ajs2a42e282004-12-08 18:43:03 +0000549 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000550 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000551 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000552 }
553 }
554
paul0bfeca32004-09-24 08:07:54 +0000555 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000556 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000557 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000558 }
559
560 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000561 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
562 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000563 iph->ip_off &= (~IP_MF);
564}
565#endif /* WANT_OSPF_WRITE_FRAGMENT */
566
ajs5dcbdf82005-03-29 16:13:49 +0000567static int
paul718e3742002-12-13 20:15:29 +0000568ospf_write (struct thread *thread)
569{
paul68980082003-03-25 05:07:42 +0000570 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000571 struct ospf_interface *oi;
572 struct ospf_packet *op;
573 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000574 struct ip iph;
575 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000576 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000577 u_char type;
578 int ret;
579 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000580 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000581#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000582 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000583#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000584 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000585#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000586
paul68980082003-03-25 05:07:42 +0000587 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000588
paul68980082003-03-25 05:07:42 +0000589 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000590 assert (node);
591 oi = getdata (node);
592 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000593
594#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000595 /* seed ipid static with low order bits of time */
596 if (ipid == 0)
597 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000598#endif /* WANT_OSPF_WRITE_FRAGMENT */
599
paul68b73392004-09-12 14:21:37 +0000600 /* convenience - max OSPF data per packet */
601 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
602
paul718e3742002-12-13 20:15:29 +0000603 /* Get one packet from queue. */
604 op = ospf_fifo_head (oi->obuf);
605 assert (op);
606 assert (op->length >= OSPF_HEADER_SIZE);
607
paul68980082003-03-25 05:07:42 +0000608 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
609 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000610 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
611
paul718e3742002-12-13 20:15:29 +0000612 /* Rewrite the md5 signature & update the seq */
613 ospf_make_md5_digest (oi, op);
614
paul37ccfa32004-10-31 11:24:51 +0000615 /* Retrieve OSPF packet type. */
616 stream_set_getp (op->s, 1);
617 type = stream_getc (op->s);
618
paul68b73392004-09-12 14:21:37 +0000619 /* reset get pointer */
620 stream_set_getp (op->s, 0);
621
622 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000623 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000624
paul718e3742002-12-13 20:15:29 +0000625 sa_dst.sin_family = AF_INET;
626#ifdef HAVE_SIN_LEN
627 sa_dst.sin_len = sizeof(sa_dst);
628#endif /* HAVE_SIN_LEN */
629 sa_dst.sin_addr = op->dst;
630 sa_dst.sin_port = htons (0);
631
632 /* Set DONTROUTE flag if dst is unicast. */
633 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
634 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
635 flags = MSG_DONTROUTE;
636
paul68b73392004-09-12 14:21:37 +0000637 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
638 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000639 if ( sizeof (struct ip)
640 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000641 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
642
paul718e3742002-12-13 20:15:29 +0000643 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000644 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000645 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000646
paul0bfeca32004-09-24 08:07:54 +0000647#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000648 /* XXX-MT: not thread-safe at all..
649 * XXX: this presumes this is only programme sending OSPF packets
650 * otherwise, no guarantee ipid will be unique
651 */
652 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000653#endif /* WANT_OSPF_WRITE_FRAGMENT */
654
paul718e3742002-12-13 20:15:29 +0000655 iph.ip_off = 0;
656 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
657 iph.ip_ttl = OSPF_VL_IP_TTL;
658 else
659 iph.ip_ttl = OSPF_IP_TTL;
660 iph.ip_p = IPPROTO_OSPFIGP;
661 iph.ip_sum = 0;
662 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
663 iph.ip_dst.s_addr = op->dst.s_addr;
664
665 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000666 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000667 msg.msg_namelen = sizeof (sa_dst);
668 msg.msg_iov = iov;
669 msg.msg_iovlen = 2;
670 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000671 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
672 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000673 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000674
675 /* Sadly we can not rely on kernels to fragment packets because of either
676 * IP_HDRINCL and/or multicast destination being set.
677 */
paul0bfeca32004-09-24 08:07:54 +0000678#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000679 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000680 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
681 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000682#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000683
684 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000685 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000686 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000687 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000688
689 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000690 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000691 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000692 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000693 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000694
paul718e3742002-12-13 20:15:29 +0000695 /* Show debug sending packet. */
696 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
697 {
698 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
699 {
ajs2a42e282004-12-08 18:43:03 +0000700 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000701 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000702 stream_set_getp (op->s, 0);
703 ospf_packet_dump (op->s);
704 }
705
ajs2a42e282004-12-08 18:43:03 +0000706 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000707 ospf_packet_type_str[type], inet_ntoa (op->dst),
708 IF_NAME (oi));
709
710 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000711 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000712 }
713
714 /* Now delete packet from queue. */
715 ospf_packet_delete (oi);
716
717 if (ospf_fifo_head (oi->obuf) == NULL)
718 {
719 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000720 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000724 if (!list_isempty (ospf->oi_write_q))
725 ospf->t_write =
726 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000727
728 return 0;
729}
730
731/* OSPF Hello message read -- RFC2328 Section 10.5. */
732void
733ospf_hello (struct ip *iph, struct ospf_header *ospfh,
734 struct stream * s, struct ospf_interface *oi, int size)
735{
736 struct ospf_hello *hello;
737 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000738 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000739 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000740
741 /* increment statistics. */
742 oi->hello_in++;
743
744 hello = (struct ospf_hello *) STREAM_PNT (s);
745
746 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000747 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000748 {
749 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
750 {
ajs2a42e282004-12-08 18:43:03 +0000751 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000752 "dropping.",
753 ospf_packet_type_str[ospfh->type],
754 inet_ntoa (iph->ip_src));
755 }
756 return;
757 }
paul718e3742002-12-13 20:15:29 +0000758
759 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000760 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000761 char buf[3][INET_ADDRSTRLEN];
762 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
763 "should not receive hellos on passive interface %s!",
764 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
765 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
766 inet_ntop(AF_INET, &oi->address->u.prefix4,
767 buf[2], sizeof(buf[2])));
768 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
769 {
770 /* Try to fix multicast membership. */
771 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
772 ospf_if_set_multicast(oi);
773 }
paul718e3742002-12-13 20:15:29 +0000774 return;
paulf2c80652002-12-13 21:44:27 +0000775 }
paul718e3742002-12-13 20:15:29 +0000776
777 /* get neighbor prefix. */
778 p.family = AF_INET;
779 p.prefixlen = ip_masklen (hello->network_mask);
780 p.u.prefix4 = iph->ip_src;
781
782 /* Compare network mask. */
783 /* Checking is ignored for Point-to-Point and Virtual link. */
784 if (oi->type != OSPF_IFTYPE_POINTOPOINT
785 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
786 if (oi->address->prefixlen != p.prefixlen)
787 {
788 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
789 inet_ntoa (ospfh->router_id));
790 return;
791 }
792
793 /* Compare Hello Interval. */
794 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
795 {
796 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
797 inet_ntoa (ospfh->router_id));
798 return;
799 }
800
801 /* Compare Router Dead Interval. */
802 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
803 {
804 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
805 inet_ntoa (ospfh->router_id));
806 return;
807 }
808
809 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000810 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000811 inet_ntoa (ospfh->router_id),
812 ospf_options_dump (hello->options));
813
814 /* Compare options. */
815#define REJECT_IF_TBIT_ON 1 /* XXX */
816#ifdef REJECT_IF_TBIT_ON
817 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
818 {
819 /*
820 * This router does not support non-zero TOS.
821 * Drop this Hello packet not to establish neighbor relationship.
822 */
823 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
824 inet_ntoa (ospfh->router_id));
825 return;
826 }
827#endif /* REJECT_IF_TBIT_ON */
828
829#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000830 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000831 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
832 {
833 /*
834 * This router does know the correct usage of O-bit
835 * the bit should be set in DD packet only.
836 */
837 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
838 inet_ntoa (ospfh->router_id));
839#ifdef STRICT_OBIT_USAGE_CHECK
840 return; /* Reject this packet. */
841#else /* STRICT_OBIT_USAGE_CHECK */
842 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
843#endif /* STRICT_OBIT_USAGE_CHECK */
844 }
845#endif /* HAVE_OPAQUE_LSA */
846
847 /* new for NSSA is to ensure that NP is on and E is off */
848
paul718e3742002-12-13 20:15:29 +0000849 if (oi->area->external_routing == OSPF_AREA_NSSA)
850 {
851 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
852 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
853 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
854 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
855 {
856 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
857 return;
858 }
859 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000860 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000861 }
862 else
paul718e3742002-12-13 20:15:29 +0000863 /* The setting of the E-bit found in the Hello Packet's Options
864 field must match this area's ExternalRoutingCapability A
865 mismatch causes processing to stop and the packet to be
866 dropped. The setting of the rest of the bits in the Hello
867 Packet's Options field should be ignored. */
868 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
869 CHECK_FLAG (hello->options, OSPF_OPTION_E))
870 {
ajs3aa8d5f2004-12-11 18:00:06 +0000871 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
872 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000873 return;
874 }
paul718e3742002-12-13 20:15:29 +0000875
pauld3f0d622004-05-05 15:27:15 +0000876 /* get neighbour struct */
877 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
878
879 /* neighbour must be valid, ospf_nbr_get creates if none existed */
880 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000881
882 old_state = nbr->state;
883
884 /* Add event to thread. */
885 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
886
887 /* RFC2328 Section 9.5.1
888 If the router is not eligible to become Designated Router,
889 (snip) It must also send an Hello Packet in reply to an
890 Hello Packet received from any eligible neighbor (other than
891 the current Designated Router and Backup Designated Router). */
892 if (oi->type == OSPF_IFTYPE_NBMA)
893 if (PRIORITY(oi) == 0 && hello->priority > 0
894 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
895 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
896 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
897 OSPF_HELLO_REPLY_DELAY);
898
899 /* on NBMA network type, it happens to receive bidirectional Hello packet
900 without advance 1-Way Received event.
901 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
902 if (oi->type == OSPF_IFTYPE_NBMA &&
903 (old_state == NSM_Down || old_state == NSM_Attempt))
904 {
905 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
906 nbr->priority = hello->priority;
907 nbr->d_router = hello->d_router;
908 nbr->bd_router = hello->bd_router;
909 return;
910 }
911
paul68980082003-03-25 05:07:42 +0000912 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000913 size - OSPF_HELLO_MIN_SIZE))
914 {
915 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
916 nbr->options |= hello->options;
917 }
918 else
919 {
920 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
921 /* Set neighbor information. */
922 nbr->priority = hello->priority;
923 nbr->d_router = hello->d_router;
924 nbr->bd_router = hello->bd_router;
925 return;
926 }
927
928 /* If neighbor itself declares DR and no BDR exists,
929 cause event BackupSeen */
930 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
931 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
932 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
933
934 /* neighbor itself declares BDR. */
935 if (oi->state == ISM_Waiting &&
936 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
937 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
938
939 /* had not previously. */
940 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
941 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
942 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
943 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
944 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
945
946 /* had not previously. */
947 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
948 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
949 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
950 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
951 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
952
953 /* Neighbor priority check. */
954 if (nbr->priority >= 0 && nbr->priority != hello->priority)
955 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
956
957 /* Set neighbor information. */
958 nbr->priority = hello->priority;
959 nbr->d_router = hello->d_router;
960 nbr->bd_router = hello->bd_router;
961}
962
963/* Save DD flags/options/Seqnum received. */
964void
965ospf_db_desc_save_current (struct ospf_neighbor *nbr,
966 struct ospf_db_desc *dd)
967{
968 nbr->last_recv.flags = dd->flags;
969 nbr->last_recv.options = dd->options;
970 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
971}
972
973/* Process rest of DD packet. */
974static void
975ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
976 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
977 u_int16_t size)
978{
979 struct ospf_lsa *new, *find;
980 struct lsa_header *lsah;
981
paul9985f832005-02-09 15:51:56 +0000982 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000983 for (size -= OSPF_DB_DESC_MIN_SIZE;
984 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
985 {
986 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000987 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000988
989 /* Unknown LS type. */
990 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
991 {
ajsbec595a2004-11-30 22:38:43 +0000992 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000993 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
994 return;
995 }
996
997#ifdef HAVE_OPAQUE_LSA
998 if (IS_OPAQUE_LSA (lsah->type)
999 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1000 {
1001 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1002 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1003 return;
1004 }
1005#endif /* HAVE_OPAQUE_LSA */
1006
1007 switch (lsah->type)
1008 {
1009 case OSPF_AS_EXTERNAL_LSA:
1010#ifdef HAVE_OPAQUE_LSA
1011 case OSPF_OPAQUE_AS_LSA:
1012#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001013 /* Check for stub area. Reject if AS-External from stub but
1014 allow if from NSSA. */
1015 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001016 {
1017 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1018 lsah->type, inet_ntoa (lsah->id),
1019 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1020 "STUB" : "NSSA");
1021 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1022 return;
1023 }
1024 break;
1025 default:
1026 break;
1027 }
1028
1029 /* Create LS-request object. */
1030 new = ospf_ls_request_new (lsah);
1031
1032 /* Lookup received LSA, then add LS request list. */
1033 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1034 if (!find || ospf_lsa_more_recent (find, new) < 0)
1035 {
1036 ospf_ls_request_add (nbr, new);
1037 ospf_lsa_discard (new);
1038 }
1039 else
1040 {
1041 /* Received LSA is not recent. */
1042 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001043 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001044 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1045 ospf_lsa_discard (new);
1046 continue;
1047 }
1048 }
1049
1050 /* Master */
1051 if (IS_SET_DD_MS (nbr->dd_flags))
1052 {
1053 nbr->dd_seqnum++;
1054 /* Entire DD packet sent. */
1055 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1056 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1057 else
1058 /* Send new DD packet. */
1059 ospf_db_desc_send (nbr);
1060 }
1061 /* Slave */
1062 else
1063 {
1064 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1065
1066 /* When master's more flags is not set. */
1067 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1068 {
1069 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1070 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1071 }
1072
ajsbec595a2004-11-30 22:38:43 +00001073 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001074 ospf_db_desc_send (nbr);
1075 }
1076
1077 /* Save received neighbor values from DD. */
1078 ospf_db_desc_save_current (nbr, dd);
1079}
1080
1081int
1082ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1083{
1084 /* Is DD duplicated? */
1085 if (dd->options == nbr->last_recv.options &&
1086 dd->flags == nbr->last_recv.flags &&
1087 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1088 return 1;
1089
1090 return 0;
1091}
1092
1093/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001094static void
paul718e3742002-12-13 20:15:29 +00001095ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1096 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1097{
1098 struct ospf_db_desc *dd;
1099 struct ospf_neighbor *nbr;
1100
1101 /* Increment statistics. */
1102 oi->db_desc_in++;
1103
1104 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001105
pauld3f0d622004-05-05 15:27:15 +00001106 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001107 if (nbr == NULL)
1108 {
1109 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1110 inet_ntoa (ospfh->router_id));
1111 return;
1112 }
1113
1114 /* Check MTU. */
1115 if (ntohs (dd->mtu) > oi->ifp->mtu)
1116 {
ajs3aa8d5f2004-12-11 18:00:06 +00001117 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1118 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1119 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001120 return;
1121 }
1122
pauld363df22003-06-19 00:26:34 +00001123 /*
1124 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1125 * required. In fact at least JunOS sends DD packets with P bit clear.
1126 * Until proper solution is developped, this hack should help.
1127 *
1128 * Update: According to the RFCs, N bit is specified /only/ for Hello
1129 * options, unfortunately its use in DD options is not specified. Hence some
1130 * implementations follow E-bit semantics and set it in DD options, and some
1131 * treat it as unspecified and hence follow the directive "default for
1132 * options is clear", ie unset.
1133 *
1134 * Reset the flag, as ospfd follows E-bit semantics.
1135 */
1136 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1137 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1138 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1139 {
1140 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001141 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001142 inet_ntoa (nbr->router_id) );
1143 SET_FLAG (dd->options, OSPF_OPTION_NP);
1144 }
pauld363df22003-06-19 00:26:34 +00001145
paul718e3742002-12-13 20:15:29 +00001146#ifdef REJECT_IF_TBIT_ON
1147 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1148 {
1149 /*
1150 * In Hello protocol, optional capability must have checked
1151 * to prevent this T-bit enabled router be my neighbor.
1152 */
1153 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1154 return;
1155 }
1156#endif /* REJECT_IF_TBIT_ON */
1157
1158#ifdef HAVE_OPAQUE_LSA
1159 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001160 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001161 {
1162 /*
1163 * This node is not configured to handle O-bit, for now.
1164 * Clear it to ignore unsupported capability proposed by neighbor.
1165 */
1166 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1167 }
1168#endif /* HAVE_OPAQUE_LSA */
1169
1170 /* Process DD packet by neighbor status. */
1171 switch (nbr->state)
1172 {
1173 case NSM_Down:
1174 case NSM_Attempt:
1175 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001176 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001177 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001178 LOOKUP (ospf_nsm_state_msg, nbr->state));
1179 break;
1180 case NSM_Init:
1181 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1182 /* If the new state is ExStart, the processing of the current
1183 packet should then continue in this new state by falling
1184 through to case ExStart below. */
1185 if (nbr->state != NSM_ExStart)
1186 break;
1187 case NSM_ExStart:
1188 /* Initial DBD */
1189 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1190 (size == OSPF_DB_DESC_MIN_SIZE))
1191 {
paul68980082003-03-25 05:07:42 +00001192 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001193 {
1194 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001195 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001196 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001197 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1198 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1199 }
1200 else
1201 {
1202 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001203 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1204 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001205 break;
1206 }
1207 }
1208 /* Ack from the Slave */
1209 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1210 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001211 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001212 {
ajs17eaa722004-12-29 21:04:48 +00001213 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001214 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001215 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1216 }
1217 else
1218 {
ajs3aa8d5f2004-12-11 18:00:06 +00001219 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1220 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001221 break;
1222 }
1223
1224 /* This is where the real Options are saved */
1225 nbr->options = dd->options;
1226
1227#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001228 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001229 {
1230 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001231 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001232 inet_ntoa (nbr->router_id),
1233 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1234
1235 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1236 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1237 {
1238 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1239 /* This situation is undesirable, but not a real error. */
1240 }
1241 }
1242#endif /* HAVE_OPAQUE_LSA */
1243
1244 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1245
1246 /* continue processing rest of packet. */
1247 ospf_db_desc_proc (s, oi, nbr, dd, size);
1248 break;
1249 case NSM_Exchange:
1250 if (ospf_db_desc_is_dup (dd, nbr))
1251 {
1252 if (IS_SET_DD_MS (nbr->dd_flags))
1253 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001254 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1255 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001256 else
1257 /* Slave: cause to retransmit the last Database Description. */
1258 {
ajs3aa8d5f2004-12-11 18:00:06 +00001259 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1260 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001261 ospf_db_desc_resend (nbr);
1262 }
1263 break;
1264 }
1265
1266 /* Otherwise DD packet should be checked. */
1267 /* Check Master/Slave bit mismatch */
1268 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1269 {
ajs3aa8d5f2004-12-11 18:00:06 +00001270 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1271 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001272 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1273 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001274 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001275 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001276 break;
1277 }
1278
1279 /* Check initialize bit is set. */
1280 if (IS_SET_DD_I (dd->flags))
1281 {
ajs3aa8d5f2004-12-11 18:00:06 +00001282 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1283 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001284 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1285 break;
1286 }
1287
1288 /* Check DD Options. */
1289 if (dd->options != nbr->options)
1290 {
1291#ifdef ORIGINAL_CODING
1292 /* Save the new options for debugging */
1293 nbr->options = dd->options;
1294#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001295 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1296 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001297 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1298 break;
1299 }
1300
1301 /* Check DD sequence number. */
1302 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1303 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1304 (!IS_SET_DD_MS (nbr->dd_flags) &&
1305 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1306 {
ajs3aa8d5f2004-12-11 18:00:06 +00001307 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1308 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001309 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1310 break;
1311 }
1312
1313 /* Continue processing rest of packet. */
1314 ospf_db_desc_proc (s, oi, nbr, dd, size);
1315 break;
1316 case NSM_Loading:
1317 case NSM_Full:
1318 if (ospf_db_desc_is_dup (dd, nbr))
1319 {
1320 if (IS_SET_DD_MS (nbr->dd_flags))
1321 {
1322 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001323 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1324 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001325 break;
1326 }
1327 else
1328 {
1329 struct timeval t, now;
1330 gettimeofday (&now, NULL);
1331 t = tv_sub (now, nbr->last_send_ts);
1332 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1333 {
1334 /* In states Loading and Full the slave must resend
1335 its last Database Description packet in response to
1336 duplicate Database Description packets received
1337 from the master. For this reason the slave must
1338 wait RouterDeadInterval seconds before freeing the
1339 last Database Description packet. Reception of a
1340 Database Description packet from the master after
1341 this interval will generate a SeqNumberMismatch
1342 neighbor event. RFC2328 Section 10.8 */
1343 ospf_db_desc_resend (nbr);
1344 break;
1345 }
1346 }
1347 }
1348
1349 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1350 break;
1351 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001352 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1353 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001354 break;
1355 }
1356}
1357
1358#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1359
1360/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1361void
1362ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1363 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1364{
1365 struct ospf_neighbor *nbr;
1366 u_int32_t ls_type;
1367 struct in_addr ls_id;
1368 struct in_addr adv_router;
1369 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001370 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001371 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001372
1373 /* Increment statistics. */
1374 oi->ls_req_in++;
1375
pauld3f0d622004-05-05 15:27:15 +00001376 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001377 if (nbr == NULL)
1378 {
1379 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1380 inet_ntoa (ospfh->router_id));
1381 return;
1382 }
1383
1384 /* Neighbor State should be Exchange or later. */
1385 if (nbr->state != NSM_Exchange &&
1386 nbr->state != NSM_Loading &&
1387 nbr->state != NSM_Full)
1388 {
ajsbec595a2004-11-30 22:38:43 +00001389 zlog_warn ("Link State Request received from %s: "
1390 "Neighbor state is %s, packet discarded.",
1391 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001392 LOOKUP (ospf_nsm_state_msg, nbr->state));
1393 return;
1394 }
1395
1396 /* Send Link State Update for ALL requested LSAs. */
1397 ls_upd = list_new ();
1398 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1399
1400 while (size >= OSPF_LSA_KEY_SIZE)
1401 {
1402 /* Get one slice of Link State Request. */
1403 ls_type = stream_getl (s);
1404 ls_id.s_addr = stream_get_ipv4 (s);
1405 adv_router.s_addr = stream_get_ipv4 (s);
1406
1407 /* Verify LSA type. */
1408 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1409 {
1410 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1411 list_delete (ls_upd);
1412 return;
1413 }
1414
1415 /* Search proper LSA in LSDB. */
1416 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1417 if (find == NULL)
1418 {
1419 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1420 list_delete (ls_upd);
1421 return;
1422 }
1423
gdt86f1fd92005-01-10 14:20:43 +00001424 /* Packet overflows MTU size, send immediately. */
1425 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001426 {
1427 if (oi->type == OSPF_IFTYPE_NBMA)
1428 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1429 else
1430 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1431
1432 /* Only remove list contents. Keep ls_upd. */
1433 list_delete_all_node (ls_upd);
1434
1435 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1436 }
1437
1438 /* Append LSA to update list. */
1439 listnode_add (ls_upd, find);
1440 length += ntohs (find->data->length);
1441
1442 size -= OSPF_LSA_KEY_SIZE;
1443 }
1444
1445 /* Send rest of Link State Update. */
1446 if (listcount (ls_upd) > 0)
1447 {
1448 if (oi->type == OSPF_IFTYPE_NBMA)
1449 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1450 else
1451 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1452
1453 list_delete (ls_upd);
1454 }
1455 else
1456 list_free (ls_upd);
1457}
1458
1459/* Get the list of LSAs from Link State Update packet.
1460 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001461static struct list *
paul718e3742002-12-13 20:15:29 +00001462ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1463 struct ospf_interface *oi, size_t size)
1464{
1465 u_int16_t count, sum;
1466 u_int32_t length;
1467 struct lsa_header *lsah;
1468 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001469 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001470
1471 lsas = list_new ();
1472
1473 count = stream_getl (s);
1474 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1475
1476 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001477 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001478 {
1479 lsah = (struct lsa_header *) STREAM_PNT (s);
1480 length = ntohs (lsah->length);
1481
1482 if (length > size)
1483 {
1484 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1485 break;
1486 }
1487
1488 /* Validate the LSA's LS checksum. */
1489 sum = lsah->checksum;
1490 if (sum != ospf_lsa_checksum (lsah))
1491 {
1492 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1493 sum, lsah->checksum);
1494 continue;
1495 }
1496
1497 /* Examine the LSA's LS type. */
1498 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1499 {
1500 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1501 continue;
1502 }
1503
1504 /*
1505 * What if the received LSA's age is greater than MaxAge?
1506 * Treat it as a MaxAge case -- endo.
1507 */
1508 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1509 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1510
1511#ifdef HAVE_OPAQUE_LSA
1512 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1513 {
1514#ifdef STRICT_OBIT_USAGE_CHECK
1515 if ((IS_OPAQUE_LSA(lsah->type) &&
1516 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1517 || (! IS_OPAQUE_LSA(lsah->type) &&
1518 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1519 {
1520 /*
1521 * This neighbor must know the exact usage of O-bit;
1522 * the bit will be set in Type-9,10,11 LSAs only.
1523 */
1524 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1525 continue;
1526 }
1527#endif /* STRICT_OBIT_USAGE_CHECK */
1528
1529 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1530 if (lsah->type == OSPF_OPAQUE_AS_LSA
1531 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1532 {
1533 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001534 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 +00001535 continue;
1536 }
1537 }
1538 else if (IS_OPAQUE_LSA(lsah->type))
1539 {
1540 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1541 continue;
1542 }
1543#endif /* HAVE_OPAQUE_LSA */
1544
1545 /* Create OSPF LSA instance. */
1546 lsa = ospf_lsa_new ();
1547
1548 /* We may wish to put some error checking if type NSSA comes in
1549 and area not in NSSA mode */
1550 switch (lsah->type)
1551 {
1552 case OSPF_AS_EXTERNAL_LSA:
1553#ifdef HAVE_OPAQUE_LSA
1554 case OSPF_OPAQUE_AS_LSA:
1555 lsa->area = NULL;
1556 break;
1557 case OSPF_OPAQUE_LINK_LSA:
1558 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1559 /* Fallthrough */
1560#endif /* HAVE_OPAQUE_LSA */
1561 default:
1562 lsa->area = oi->area;
1563 break;
1564 }
1565
1566 lsa->data = ospf_lsa_data_new (length);
1567 memcpy (lsa->data, lsah, length);
1568
1569 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001570 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001571 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1572 listnode_add (lsas, lsa);
1573 }
1574
1575 return lsas;
1576}
1577
1578/* Cleanup Update list. */
1579void
hasso52dc7ee2004-09-23 19:18:23 +00001580ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001581{
hasso52dc7ee2004-09-23 19:18:23 +00001582 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001583 struct ospf_lsa *lsa;
1584
1585 for (node = listhead (lsas); node; nextnode (node))
1586 if ((lsa = getdata (node)) != NULL)
1587 ospf_lsa_discard (lsa);
1588
1589 list_delete (lsas);
1590}
1591
1592/* OSPF Link State Update message read -- RFC2328 Section 13. */
1593void
1594ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1595 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1596{
1597 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001598 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001599#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001600 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001601#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001602 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001603 struct ospf_lsa *lsa = NULL;
1604 /* unsigned long ls_req_found = 0; */
1605
1606 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1607
1608 /* Increment statistics. */
1609 oi->ls_upd_in++;
1610
1611 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001612 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001613 if (nbr == NULL)
1614 {
1615 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1616 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1617 return;
1618 }
1619
1620 /* Check neighbor state. */
1621 if (nbr->state < NSM_Exchange)
1622 {
ajs3aa8d5f2004-12-11 18:00:06 +00001623 zlog_warn ("Link State Update: "
1624 "Neighbor[%s] state %s is less than Exchange",
1625 inet_ntoa (ospfh->router_id),
1626 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001627 return;
1628 }
1629
1630 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1631 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1632 * of section 13.
1633 */
1634 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1635
1636#ifdef HAVE_OPAQUE_LSA
1637 /*
1638 * Prepare two kinds of lists to clean up unwanted self-originated
1639 * Opaque-LSAs from the routing domain as soon as possible.
1640 */
1641 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1642 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1643
1644 /*
1645 * If self-originated Opaque-LSAs that have flooded before restart
1646 * are contained in the received LSUpd message, corresponding LSReq
1647 * messages to be sent may have to be modified.
1648 * To eliminate possible race conditions such that flushing and normal
1649 * updating for the same LSA would take place alternately, this trick
1650 * must be done before entering to the loop below.
1651 */
1652 ospf_opaque_adjust_lsreq (nbr, lsas);
1653#endif /* HAVE_OPAQUE_LSA */
1654
1655#define DISCARD_LSA(L,N) {\
1656 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001657 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 +00001658 ospf_lsa_discard (L); \
1659 continue; }
1660
1661 /* Process each LSA received in the one packet. */
1662 for (node = listhead (lsas); node; node = next)
1663 {
1664 struct ospf_lsa *ls_ret, *current;
1665 int ret = 1;
1666
1667 next = node->next;
1668
1669 lsa = getdata (node);
1670
paul718e3742002-12-13 20:15:29 +00001671 if (IS_DEBUG_OSPF_NSSA)
1672 {
1673 char buf1[INET_ADDRSTRLEN];
1674 char buf2[INET_ADDRSTRLEN];
1675 char buf3[INET_ADDRSTRLEN];
1676
ajs2a42e282004-12-08 18:43:03 +00001677 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001678 lsa->data->type,
1679 inet_ntop (AF_INET, &ospfh->router_id,
1680 buf1, INET_ADDRSTRLEN),
1681 inet_ntop (AF_INET, &lsa->data->id,
1682 buf2, INET_ADDRSTRLEN),
1683 inet_ntop (AF_INET, &lsa->data->adv_router,
1684 buf3, INET_ADDRSTRLEN));
1685 }
paul718e3742002-12-13 20:15:29 +00001686
1687 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1688
1689 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1690
1691 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1692
1693 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1694
1695 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1696
1697 /* Do take in Type-7's if we are an NSSA */
1698
1699 /* If we are also an ABR, later translate them to a Type-5 packet */
1700
1701 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1702 translate them to a separate Type-5 packet. */
1703
1704 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1705 /* Reject from STUB or NSSA */
1706 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1707 {
1708 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001709 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001710 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001711 }
1712
paul718e3742002-12-13 20:15:29 +00001713 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1714 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1715 {
1716 DISCARD_LSA (lsa,2);
1717 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001718 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001719 }
paul718e3742002-12-13 20:15:29 +00001720
1721 /* Find the LSA in the current database. */
1722
1723 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1724
1725 /* If the LSA's LS age is equal to MaxAge, and there is currently
1726 no instance of the LSA in the router's link state database,
1727 and none of router's neighbors are in states Exchange or Loading,
1728 then take the following actions. */
1729
1730 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001731 (ospf_nbr_count (oi, NSM_Exchange) +
1732 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001733 {
1734 /* Response Link State Acknowledgment. */
1735 ospf_ls_ack_send (nbr, lsa);
1736
1737 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001738 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1739 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001740 DISCARD_LSA (lsa, 3);
1741 }
1742
1743#ifdef HAVE_OPAQUE_LSA
1744 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001745 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001746 {
1747 /*
1748 * Even if initial flushing seems to be completed, there might
1749 * be a case that self-originated LSA with MaxAge still remain
1750 * in the routing domain.
1751 * Just send an LSAck message to cease retransmission.
1752 */
1753 if (IS_LSA_MAXAGE (lsa))
1754 {
1755 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1756 ospf_ls_ack_send (nbr, lsa);
1757 ospf_lsa_discard (lsa);
1758
1759 if (current != NULL && ! IS_LSA_MAXAGE (current))
1760 ospf_opaque_lsa_refresh_schedule (current);
1761 continue;
1762 }
1763
1764 /*
1765 * If an instance of self-originated Opaque-LSA is not found
1766 * in the LSDB, there are some possible cases here.
1767 *
1768 * 1) This node lost opaque-capability after restart.
1769 * 2) Else, a part of opaque-type is no more supported.
1770 * 3) Else, a part of opaque-id is no more supported.
1771 *
1772 * Anyway, it is still this node's responsibility to flush it.
1773 * Otherwise, the LSA instance remains in the routing domain
1774 * until its age reaches to MaxAge.
1775 */
1776 if (current == NULL)
1777 {
1778 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001779 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001780
1781 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1782 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1783 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1784 continue;
1785 }
1786 }
1787#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001788 /* It might be happen that received LSA is self-originated network LSA, but
1789 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1790 * Link State ID is one of the router's own IP interface addresses but whose
1791 * Advertising Router is not equal to the router's own Router ID
1792 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1793 */
1794
1795 if(lsa->data->type == OSPF_NETWORK_LSA)
1796 {
hasso52dc7ee2004-09-23 19:18:23 +00001797 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001798 int Flag = 0;
1799
1800 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1801 {
1802 struct ospf_interface *out_if = getdata(oi_node);
1803 if(out_if == NULL)
1804 break;
1805
1806 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1807 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1808 {
1809 if(out_if->network_lsa_self)
1810 {
1811 ospf_lsa_flush_area(lsa,out_if->area);
1812 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001813 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001814 lsa, (int) lsa->data->type);
1815 ospf_lsa_discard (lsa);
1816 Flag = 1;
1817 }
1818 break;
1819 }
1820 }
1821 if(Flag)
1822 continue;
1823 }
paul718e3742002-12-13 20:15:29 +00001824
1825 /* (5) Find the instance of this LSA that is currently contained
1826 in the router's link state database. If there is no
1827 database copy, or the received LSA is more recent than
1828 the database copy the following steps must be performed. */
1829
1830 if (current == NULL ||
1831 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1832 {
1833 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001834 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001835 DISCARD_LSA (lsa, 4);
1836 continue;
1837 }
1838
1839 /* (6) Else, If there is an instance of the LSA on the sending
1840 neighbor's Link state request list, an error has occurred in
1841 the Database Exchange process. In this case, restart the
1842 Database Exchange process by generating the neighbor event
1843 BadLSReq for the sending neighbor and stop processing the
1844 Link State Update packet. */
1845
1846 if (ospf_ls_request_lookup (nbr, lsa))
1847 {
1848 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001849 zlog_warn("LSA[%s] instance exists on Link state request list",
1850 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001851
1852 /* Clean list of LSAs. */
1853 ospf_upd_list_clean (lsas);
1854 /* this lsa is not on lsas list already. */
1855 ospf_lsa_discard (lsa);
1856#ifdef HAVE_OPAQUE_LSA
1857 list_delete (mylsa_acks);
1858 list_delete (mylsa_upds);
1859#endif /* HAVE_OPAQUE_LSA */
1860 return;
1861 }
1862
1863 /* If the received LSA is the same instance as the database copy
1864 (i.e., neither one is more recent) the following two steps
1865 should be performed: */
1866
1867 if (ret == 0)
1868 {
1869 /* If the LSA is listed in the Link state retransmission list
1870 for the receiving adjacency, the router itself is expecting
1871 an acknowledgment for this LSA. The router should treat the
1872 received LSA as an acknowledgment by removing the LSA from
1873 the Link state retransmission list. This is termed an
1874 "implied acknowledgment". */
1875
1876 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1877
1878 if (ls_ret != NULL)
1879 {
1880 ospf_ls_retransmit_delete (nbr, ls_ret);
1881
1882 /* Delayed acknowledgment sent if advertisement received
1883 from Designated Router, otherwise do nothing. */
1884 if (oi->state == ISM_Backup)
1885 if (NBR_IS_DR (nbr))
1886 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1887
1888 DISCARD_LSA (lsa, 5);
1889 }
1890 else
1891 /* Acknowledge the receipt of the LSA by sending a
1892 Link State Acknowledgment packet back out the receiving
1893 interface. */
1894 {
1895 ospf_ls_ack_send (nbr, lsa);
1896 DISCARD_LSA (lsa, 6);
1897 }
1898 }
1899
1900 /* The database copy is more recent. If the database copy
1901 has LS age equal to MaxAge and LS sequence number equal to
1902 MaxSequenceNumber, simply discard the received LSA without
1903 acknowledging it. (In this case, the LSA's LS sequence number is
1904 wrapping, and the MaxSequenceNumber LSA must be completely
1905 flushed before any new LSA instance can be introduced). */
1906
1907 else if (ret > 0) /* Database copy is more recent */
1908 {
1909 if (IS_LSA_MAXAGE (current) &&
1910 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1911 {
1912 DISCARD_LSA (lsa, 7);
1913 }
1914 /* Otherwise, as long as the database copy has not been sent in a
1915 Link State Update within the last MinLSArrival seconds, send the
1916 database copy back to the sending neighbor, encapsulated within
1917 a Link State Update Packet. The Link State Update Packet should
1918 be sent directly to the neighbor. In so doing, do not put the
1919 database copy of the LSA on the neighbor's link state
1920 retransmission list, and do not acknowledge the received (less
1921 recent) LSA instance. */
1922 else
1923 {
1924 struct timeval now;
1925
1926 gettimeofday (&now, NULL);
1927
1928 if (tv_cmp (tv_sub (now, current->tv_orig),
1929 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1930 /* Trap NSSA type later.*/
1931 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1932 DISCARD_LSA (lsa, 8);
1933 }
1934 }
1935 }
1936
1937#ifdef HAVE_OPAQUE_LSA
1938 /*
1939 * Now that previously originated Opaque-LSAs those which not yet
1940 * installed into LSDB are captured, take several steps to clear
1941 * them completely from the routing domain, before proceeding to
1942 * origination for the current target Opaque-LSAs.
1943 */
1944 while (listcount (mylsa_acks) > 0)
1945 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1946
1947 if (listcount (mylsa_upds) > 0)
1948 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1949
1950 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001951 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001952#endif /* HAVE_OPAQUE_LSA */
1953
1954 assert (listcount (lsas) == 0);
1955 list_delete (lsas);
1956}
1957
1958/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1959void
1960ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1961 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1962{
1963 struct ospf_neighbor *nbr;
1964#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001965 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001966#endif /* HAVE_OPAQUE_LSA */
1967
1968 /* increment statistics. */
1969 oi->ls_ack_in++;
1970
pauld3f0d622004-05-05 15:27:15 +00001971 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001972 if (nbr == NULL)
1973 {
1974 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1975 inet_ntoa (ospfh->router_id));
1976 return;
1977 }
1978
1979 if (nbr->state < NSM_Exchange)
1980 {
ajs3aa8d5f2004-12-11 18:00:06 +00001981 zlog_warn ("Link State Acknowledgment: "
1982 "Neighbor[%s] state %s is less than Exchange",
1983 inet_ntoa (ospfh->router_id),
1984 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001985 return;
1986 }
1987
1988#ifdef HAVE_OPAQUE_LSA
1989 opaque_acks = list_new ();
1990#endif /* HAVE_OPAQUE_LSA */
1991
1992 while (size >= OSPF_LSA_HEADER_SIZE)
1993 {
1994 struct ospf_lsa *lsa, *lsr;
1995
1996 lsa = ospf_lsa_new ();
1997 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1998
1999 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2000 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002001 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002002
2003 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2004 {
2005 lsa->data = NULL;
2006 ospf_lsa_discard (lsa);
2007 continue;
2008 }
2009
2010 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2011
2012 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2013 {
2014#ifdef HAVE_OPAQUE_LSA
2015 /* Keep this LSA entry for later reference. */
2016 if (IS_OPAQUE_LSA (lsr->data->type))
2017 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2018#endif /* HAVE_OPAQUE_LSA */
2019
2020 ospf_ls_retransmit_delete (nbr, lsr);
2021 }
2022
2023 lsa->data = NULL;
2024 ospf_lsa_discard (lsa);
2025 }
2026
2027#ifdef HAVE_OPAQUE_LSA
2028 if (listcount (opaque_acks) > 0)
2029 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2030
2031 list_delete (opaque_acks);
2032 return;
2033#endif /* HAVE_OPAQUE_LSA */
2034}
2035
ajs038163f2005-02-17 19:55:59 +00002036static struct stream *
ajs5c333492005-02-23 15:43:01 +00002037ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002038{
2039 int ret;
ajs5c333492005-02-23 15:43:01 +00002040 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002041 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002042 unsigned int ifindex = 0;
2043 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002044 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002045 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002046 struct msghdr msgh;
2047
paul68defd62004-09-27 07:27:13 +00002048 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002049 msgh.msg_iov = &iov;
2050 msgh.msg_iovlen = 1;
2051 msgh.msg_control = (caddr_t) buff;
2052 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002053
ajs5c333492005-02-23 15:43:01 +00002054 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2055 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002056 {
ajs5c333492005-02-23 15:43:01 +00002057 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2058 return NULL;
2059 }
2060 if (ret < sizeof(iph))
2061 {
2062 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2063 "(ip header size is %u)",
2064 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002065 return NULL;
2066 }
paul18b12c32004-10-05 14:38:29 +00002067
ajs5c333492005-02-23 15:43:01 +00002068 /* Note that there should not be alignment problems with this assignment
2069 because this is at the beginning of the stream data buffer. */
2070 iph = (struct ip *) STREAM_DATA(ibuf);
2071 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002072
ajs5c333492005-02-23 15:43:01 +00002073 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002074
paul239aecc2003-12-08 10:34:54 +00002075#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002076 /*
2077 * Kernel network code touches incoming IP header parameters,
2078 * before protocol specific processing.
2079 *
2080 * 1) Convert byteorder to host representation.
2081 * --> ip_len, ip_id, ip_off
2082 *
2083 * 2) Adjust ip_len to strip IP header size!
2084 * --> If user process receives entire IP packet via RAW
2085 * socket, it must consider adding IP header size to
2086 * the "ip_len" field of "ip" structure.
2087 *
2088 * For more details, see <netinet/ip_input.c>.
2089 */
ajs5c333492005-02-23 15:43:01 +00002090 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002091#endif
2092
paul863082d2004-08-19 04:43:43 +00002093 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002094
2095 *ifp = if_lookup_by_index (ifindex);
2096
2097 if (ret != ip_len)
2098 {
ajs5c333492005-02-23 15:43:01 +00002099 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2100 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002101 return NULL;
2102 }
2103
2104 return ibuf;
2105}
2106
2107struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002108ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002109 struct ip *iph, struct ospf_header *ospfh)
2110{
2111 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002112 struct ospf_vl_data *vl_data;
2113 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002114 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002115
2116 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2117 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002118 return NULL;
paul718e3742002-12-13 20:15:29 +00002119
pauld3f0d622004-05-05 15:27:15 +00002120 /* look for local OSPF interface matching the destination
2121 * to determine Area ID. We presume therefore the destination address
2122 * is unique, or at least (for "unnumbered" links), not used in other
2123 * areas
2124 */
2125 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2126 iph->ip_dst)) == NULL)
2127 return NULL;
paul718e3742002-12-13 20:15:29 +00002128
paul020709f2003-04-04 02:44:16 +00002129 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002130 {
2131 if ((vl_data = getdata (node)) == NULL)
2132 continue;
2133
paul020709f2003-04-04 02:44:16 +00002134 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002135 if (!vl_area)
2136 continue;
2137
2138 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2139 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2140 {
2141 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002142 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002143 IF_NAME (vl_data->vl_oi));
2144 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2145 {
2146 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002147 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002148 return NULL;
2149 }
2150
2151 return vl_data->vl_oi;
2152 }
2153 }
2154
2155 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002156 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002157
pauld3f0d622004-05-05 15:27:15 +00002158 return NULL;
paul718e3742002-12-13 20:15:29 +00002159}
2160
2161int
2162ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2163{
2164 /* Check match the Area ID of the receiving interface. */
2165 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2166 return 1;
2167
2168 return 0;
2169}
2170
2171/* Unbound socket will accept any Raw IP packets if proto is matched.
2172 To prevent it, compare src IP address and i/f address with masking
2173 i/f network mask. */
2174int
2175ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2176{
2177 struct in_addr mask, me, him;
2178
2179 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2180 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2181 return 1;
2182
2183 masklen2ip (oi->address->prefixlen, &mask);
2184
2185 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2186 him.s_addr = ip_src.s_addr & mask.s_addr;
2187
2188 if (IPV4_ADDR_SAME (&me, &him))
2189 return 1;
2190
2191 return 0;
2192}
2193
2194int
2195ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2196 struct ospf_header *ospfh)
2197{
2198 int ret = 0;
2199 struct crypt_key *ck;
2200
2201 switch (ntohs (ospfh->auth_type))
2202 {
2203 case OSPF_AUTH_NULL:
2204 ret = 1;
2205 break;
2206 case OSPF_AUTH_SIMPLE:
2207 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2208 ret = 1;
2209 else
2210 ret = 0;
2211 break;
2212 case OSPF_AUTH_CRYPTOGRAPHIC:
2213 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2214 {
2215 ret = 0;
2216 break;
2217 }
2218
2219 /* This is very basic, the digest processing is elsewhere */
2220 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2221 ospfh->u.crypt.key_id == ck->key_id &&
2222 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2223 ret = 1;
2224 else
2225 ret = 0;
2226 break;
2227 default:
2228 ret = 0;
2229 break;
2230 }
2231
2232 return ret;
2233}
2234
2235int
2236ospf_check_sum (struct ospf_header *ospfh)
2237{
2238 u_int32_t ret;
2239 u_int16_t sum;
2240 int in_cksum (void *ptr, int nbytes);
2241
2242 /* clear auth_data for checksum. */
2243 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2244
2245 /* keep checksum and clear. */
2246 sum = ospfh->checksum;
2247 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2248
2249 /* calculate checksum. */
2250 ret = in_cksum (ospfh, ntohs (ospfh->length));
2251
2252 if (ret != sum)
2253 {
2254 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2255 ret, sum);
2256 return 0;
2257 }
2258
2259 return 1;
2260}
2261
2262/* OSPF Header verification. */
2263int
2264ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2265 struct ip *iph, struct ospf_header *ospfh)
2266{
2267 /* check version. */
2268 if (ospfh->version != OSPF_VERSION)
2269 {
2270 zlog_warn ("interface %s: ospf_read version number mismatch.",
2271 IF_NAME (oi));
2272 return -1;
2273 }
2274
2275 /* Check Area ID. */
2276 if (!ospf_check_area_id (oi, ospfh))
2277 {
2278 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2279 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2280 return -1;
2281 }
2282
2283 /* Check network mask, Silently discarded. */
2284 if (! ospf_check_network_mask (oi, iph->ip_src))
2285 {
2286 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2287 IF_NAME (oi), inet_ntoa (iph->ip_src));
2288 return -1;
2289 }
2290
2291 /* Check authentication. */
2292 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2293 {
2294 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2295 IF_NAME (oi));
2296 return -1;
2297 }
2298
2299 if (! ospf_check_auth (oi, ibuf, ospfh))
2300 {
2301 zlog_warn ("interface %s: ospf_read authentication failed.",
2302 IF_NAME (oi));
2303 return -1;
2304 }
2305
2306 /* if check sum is invalid, packet is discarded. */
2307 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2308 {
2309 if (! ospf_check_sum (ospfh))
2310 {
2311 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2312 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2313 return -1;
2314 }
2315 }
2316 else
2317 {
2318 if (ospfh->checksum != 0)
2319 return -1;
2320 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2321 {
2322 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2323 IF_NAME (oi));
2324 return -1;
2325 }
2326 }
2327
2328 return 0;
2329}
2330
2331/* Starting point of packet process function. */
2332int
2333ospf_read (struct thread *thread)
2334{
2335 int ret;
2336 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002337 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002338 struct ospf_interface *oi;
2339 struct ip *iph;
2340 struct ospf_header *ospfh;
2341 u_int16_t length;
2342 struct interface *ifp;
2343
2344 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002345 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002346
2347 /* prepare for next packet. */
2348 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002349
2350 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002351 stream_reset(ospf->ibuf);
2352 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002353 return -1;
2354
ajs5c333492005-02-23 15:43:01 +00002355 /* Note that there should not be alignment problems with this assignment
2356 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002357 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002358 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002359
paulac191232004-10-22 12:05:17 +00002360 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002361 /* Handle cases where the platform does not support retrieving the ifindex,
2362 and also platforms (such as Solaris 8) that claim to support ifindex
2363 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002364 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002365
pauld3f0d622004-05-05 15:27:15 +00002366 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002367 return 0;
paul718e3742002-12-13 20:15:29 +00002368
2369 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002370 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002371 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002372
paul718e3742002-12-13 20:15:29 +00002373 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002374 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002375 {
pauld3241812003-09-29 12:42:39 +00002376 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2377 {
ajs2a42e282004-12-08 18:43:03 +00002378 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002379 inet_ntoa (iph->ip_src));
2380 }
paul718e3742002-12-13 20:15:29 +00002381 return 0;
2382 }
2383
2384 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002385 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002386
2387 /* Get ospf packet header. */
2388 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2389
2390 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002391 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002392
2393 /* if no local ospf_interface,
2394 * or header area is backbone but ospf_interface is not
2395 * check for VLINK interface
2396 */
2397 if ( (oi == NULL) ||
2398 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2399 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2400 )
2401 {
2402 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2403 {
2404 zlog_warn ("Packet from [%s] received on link %s"
2405 " but no ospf_interface",
2406 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002407 return 0;
2408 }
2409 }
2410
2411 /* else it must be a local ospf interface, check it was received on
2412 * correct link
2413 */
2414 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002415 {
2416 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002417 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002418 return 0;
2419 }
ajs847947f2005-02-02 18:38:48 +00002420 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002421 {
ajsba6454e2005-02-08 15:37:30 +00002422 char buf[2][INET_ADDRSTRLEN];
2423 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002424 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002425 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2426 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2427 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002428 /* Fix multicast memberships? */
2429 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2430 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2431 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2432 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2433 if (oi->multicast_memberships)
2434 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002435 return 0;
2436 }
paul718e3742002-12-13 20:15:29 +00002437
2438 /*
2439 * If the received packet is destined for AllDRouters, the packet
2440 * should be accepted only if the received ospf interface state is
2441 * either DR or Backup -- endo.
2442 */
2443 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2444 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2445 {
ajsba6454e2005-02-08 15:37:30 +00002446 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002447 inet_ntoa (iph->ip_src), IF_NAME (oi),
2448 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002449 /* Try to fix multicast membership. */
2450 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2451 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002452 return 0;
2453 }
2454
2455 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002456 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2457 {
paul718e3742002-12-13 20:15:29 +00002458 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002459 {
ajs2a42e282004-12-08 18:43:03 +00002460 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002461 ospf_packet_dump (ibuf);
2462 }
paul718e3742002-12-13 20:15:29 +00002463
ajs2a42e282004-12-08 18:43:03 +00002464 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002465 ospf_packet_type_str[ospfh->type],
2466 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002467 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2468 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002469
2470 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002471 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002472 }
paul718e3742002-12-13 20:15:29 +00002473
2474 /* Some header verification. */
2475 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2476 if (ret < 0)
2477 {
pauld3241812003-09-29 12:42:39 +00002478 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2479 {
ajs2a42e282004-12-08 18:43:03 +00002480 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002481 "dropping.",
2482 ospf_packet_type_str[ospfh->type],
2483 inet_ntoa (iph->ip_src));
2484 }
paul718e3742002-12-13 20:15:29 +00002485 return ret;
2486 }
2487
paul9985f832005-02-09 15:51:56 +00002488 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002489
2490 /* Adjust size to message length. */
2491 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2492
2493 /* Read rest of the packet and call each sort of packet routine. */
2494 switch (ospfh->type)
2495 {
2496 case OSPF_MSG_HELLO:
2497 ospf_hello (iph, ospfh, ibuf, oi, length);
2498 break;
2499 case OSPF_MSG_DB_DESC:
2500 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2501 break;
2502 case OSPF_MSG_LS_REQ:
2503 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2504 break;
2505 case OSPF_MSG_LS_UPD:
2506 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2507 break;
2508 case OSPF_MSG_LS_ACK:
2509 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2510 break;
2511 default:
2512 zlog (NULL, LOG_WARNING,
2513 "interface %s: OSPF packet header type %d is illegal",
2514 IF_NAME (oi), ospfh->type);
2515 break;
2516 }
2517
paul718e3742002-12-13 20:15:29 +00002518 return 0;
2519}
2520
2521/* Make OSPF header. */
2522void
2523ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2524{
2525 struct ospf_header *ospfh;
2526
2527 ospfh = (struct ospf_header *) STREAM_DATA (s);
2528
2529 ospfh->version = (u_char) OSPF_VERSION;
2530 ospfh->type = (u_char) type;
2531
paul68980082003-03-25 05:07:42 +00002532 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002533
2534 ospfh->checksum = 0;
2535 ospfh->area_id = oi->area->area_id;
2536 ospfh->auth_type = htons (ospf_auth_type (oi));
2537
2538 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2539
paul9985f832005-02-09 15:51:56 +00002540 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002541}
2542
2543/* Make Authentication Data. */
2544int
2545ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2546{
2547 struct crypt_key *ck;
2548
2549 switch (ospf_auth_type (oi))
2550 {
2551 case OSPF_AUTH_NULL:
2552 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2553 break;
2554 case OSPF_AUTH_SIMPLE:
2555 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2556 OSPF_AUTH_SIMPLE_SIZE);
2557 break;
2558 case OSPF_AUTH_CRYPTOGRAPHIC:
2559 /* If key is not set, then set 0. */
2560 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2561 {
2562 ospfh->u.crypt.zero = 0;
2563 ospfh->u.crypt.key_id = 0;
2564 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2565 }
2566 else
2567 {
2568 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2569 ospfh->u.crypt.zero = 0;
2570 ospfh->u.crypt.key_id = ck->key_id;
2571 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2572 }
2573 /* note: the seq is done in ospf_make_md5_digest() */
2574 break;
2575 default:
2576 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2577 break;
2578 }
2579
2580 return 0;
2581}
2582
2583/* Fill rest of OSPF header. */
2584void
2585ospf_fill_header (struct ospf_interface *oi,
2586 struct stream *s, u_int16_t length)
2587{
2588 struct ospf_header *ospfh;
2589
2590 ospfh = (struct ospf_header *) STREAM_DATA (s);
2591
2592 /* Fill length. */
2593 ospfh->length = htons (length);
2594
2595 /* Calculate checksum. */
2596 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2597 ospfh->checksum = in_cksum (ospfh, length);
2598 else
2599 ospfh->checksum = 0;
2600
2601 /* Add Authentication Data. */
2602 ospf_make_auth (oi, ospfh);
2603}
2604
2605int
2606ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2607{
2608 struct ospf_neighbor *nbr;
2609 struct route_node *rn;
2610 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2611 struct in_addr mask;
2612 unsigned long p;
2613 int flag = 0;
2614
2615 /* Set netmask of interface. */
2616 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2617 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2618 masklen2ip (oi->address->prefixlen, &mask);
2619 else
2620 memset ((char *) &mask, 0, sizeof (struct in_addr));
2621 stream_put_ipv4 (s, mask.s_addr);
2622
2623 /* Set Hello Interval. */
2624 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2625
2626 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002627 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002628 OPTIONS(oi), IF_NAME (oi));
2629
2630 /* Set Options. */
2631 stream_putc (s, OPTIONS (oi));
2632
2633 /* Set Router Priority. */
2634 stream_putc (s, PRIORITY (oi));
2635
2636 /* Set Router Dead Interval. */
2637 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2638
2639 /* Set Designated Router. */
2640 stream_put_ipv4 (s, DR (oi).s_addr);
2641
paul9985f832005-02-09 15:51:56 +00002642 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002643
2644 /* Set Backup Designated Router. */
2645 stream_put_ipv4 (s, BDR (oi).s_addr);
2646
2647 /* Add neighbor seen. */
2648 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002649 if ((nbr = rn->info))
2650 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2651 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2652 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2653 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002654 {
2655 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002656 if (nbr->d_router.s_addr != 0
2657 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2658 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2659 flag = 1;
paul718e3742002-12-13 20:15:29 +00002660
2661 stream_put_ipv4 (s, nbr->router_id.s_addr);
2662 length += 4;
2663 }
2664
2665 /* Let neighbor generate BackupSeen. */
2666 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002667 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002668
2669 return length;
2670}
2671
2672int
2673ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2674 struct stream *s)
2675{
2676 struct ospf_lsa *lsa;
2677 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2678 u_char options;
2679 unsigned long pp;
2680 int i;
2681 struct ospf_lsdb *lsdb;
2682
2683 /* Set Interface MTU. */
2684 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2685 stream_putw (s, 0);
2686 else
2687 stream_putw (s, oi->ifp->mtu);
2688
2689 /* Set Options. */
2690 options = OPTIONS (oi);
2691#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002692 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002693 {
2694 if (IS_SET_DD_I (nbr->dd_flags)
2695 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2696 /*
2697 * Set O-bit in the outgoing DD packet for capablity negotiation,
2698 * if one of following case is applicable.
2699 *
2700 * 1) WaitTimer expiration event triggered the neighbor state to
2701 * change to Exstart, but no (valid) DD packet has received
2702 * from the neighbor yet.
2703 *
2704 * 2) At least one DD packet with O-bit on has received from the
2705 * neighbor.
2706 */
2707 SET_FLAG (options, OSPF_OPTION_O);
2708 }
2709#endif /* HAVE_OPAQUE_LSA */
2710 stream_putc (s, options);
2711
2712 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002713 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002714 stream_putc (s, nbr->dd_flags);
2715
2716 /* Set DD Sequence Number. */
2717 stream_putl (s, nbr->dd_seqnum);
2718
2719 if (ospf_db_summary_isempty (nbr))
2720 {
2721 if (nbr->state >= NSM_Exchange)
2722 {
2723 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2724 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002725 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002726 }
2727 return length;
2728 }
2729
2730 /* Describe LSA Header from Database Summary List. */
2731 lsdb = &nbr->db_sum;
2732
2733 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2734 {
2735 struct route_table *table = lsdb->type[i].db;
2736 struct route_node *rn;
2737
2738 for (rn = route_top (table); rn; rn = route_next (rn))
2739 if ((lsa = rn->info) != NULL)
2740 {
2741#ifdef HAVE_OPAQUE_LSA
2742 if (IS_OPAQUE_LSA (lsa->data->type)
2743 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2744 {
2745 /* Suppress advertising opaque-informations. */
2746 /* Remove LSA from DB summary list. */
2747 ospf_lsdb_delete (lsdb, lsa);
2748 continue;
2749 }
2750#endif /* HAVE_OPAQUE_LSA */
2751
2752 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2753 {
2754 struct lsa_header *lsah;
2755 u_int16_t ls_age;
2756
2757 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002758 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002759 break;
2760
2761 /* Keep pointer to LS age. */
2762 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002763 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002764
2765 /* Proceed stream pointer. */
2766 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2767 length += OSPF_LSA_HEADER_SIZE;
2768
2769 /* Set LS age. */
2770 ls_age = LS_AGE (lsa);
2771 lsah->ls_age = htons (ls_age);
2772
2773 }
2774
2775 /* Remove LSA from DB summary list. */
2776 ospf_lsdb_delete (lsdb, lsa);
2777 }
2778 }
2779
2780 return length;
2781}
2782
2783int
2784ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2785 unsigned long delta, struct ospf_neighbor *nbr,
2786 struct ospf_lsa *lsa)
2787{
2788 struct ospf_interface *oi;
2789
2790 oi = nbr->oi;
2791
2792 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002793 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002794 return 0;
2795
2796 stream_putl (s, lsa->data->type);
2797 stream_put_ipv4 (s, lsa->data->id.s_addr);
2798 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2799
2800 ospf_lsa_unlock (nbr->ls_req_last);
2801 nbr->ls_req_last = ospf_lsa_lock (lsa);
2802
2803 *length += 12;
2804 return 1;
2805}
2806
2807int
2808ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2809{
2810 struct ospf_lsa *lsa;
2811 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002812 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002813 struct route_table *table;
2814 struct route_node *rn;
2815 int i;
2816 struct ospf_lsdb *lsdb;
2817
2818 lsdb = &nbr->ls_req;
2819
2820 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2821 {
2822 table = lsdb->type[i].db;
2823 for (rn = route_top (table); rn; rn = route_next (rn))
2824 if ((lsa = (rn->info)) != NULL)
2825 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2826 {
2827 route_unlock_node (rn);
2828 break;
2829 }
2830 }
2831 return length;
2832}
2833
2834int
2835ls_age_increment (struct ospf_lsa *lsa, int delay)
2836{
2837 int age;
2838
2839 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2840
2841 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2842}
2843
2844int
hasso52dc7ee2004-09-23 19:18:23 +00002845ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002846{
2847 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002848 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002849 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002850 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002851 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002852 unsigned long pp;
2853 int count = 0;
2854
2855 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002856 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002857
paul9985f832005-02-09 15:51:56 +00002858 pp = stream_get_endp (s);
2859 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002860
gdt86f1fd92005-01-10 14:20:43 +00002861 /* Calculate amount of packet usable for data. */
2862 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2863
paul718e3742002-12-13 20:15:29 +00002864 while ((node = listhead (update)) != NULL)
2865 {
2866 struct lsa_header *lsah;
2867 u_int16_t ls_age;
2868
2869 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002870 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002871
2872 lsa = getdata (node);
2873 assert (lsa);
2874 assert (lsa->data);
2875
paul68b73392004-09-12 14:21:37 +00002876 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002877 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002878 break;
2879
paul718e3742002-12-13 20:15:29 +00002880 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002881 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002882
2883 /* Put LSA to Link State Request. */
2884 stream_put (s, lsa->data, ntohs (lsa->data->length));
2885
2886 /* Set LS age. */
2887 /* each hop must increment an lsa_age by transmit_delay
2888 of OSPF interface */
2889 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2890 lsah->ls_age = htons (ls_age);
2891
2892 length += ntohs (lsa->data->length);
2893 count++;
2894
2895 list_delete_node (update, node);
2896 ospf_lsa_unlock (lsa);
2897 }
2898
2899 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002900 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002901
2902 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002903 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002904 return length;
2905}
2906
2907int
hasso52dc7ee2004-09-23 19:18:23 +00002908ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002909{
hasso52dc7ee2004-09-23 19:18:23 +00002910 struct list *rm_list;
2911 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002912 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002913 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002914 struct ospf_lsa *lsa;
2915
2916 rm_list = list_new ();
2917
2918 for (node = listhead (ack); node; nextnode (node))
2919 {
2920 lsa = getdata (node);
2921 assert (lsa);
2922
gdt86f1fd92005-01-10 14:20:43 +00002923 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002924 break;
2925
2926 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2927 length += OSPF_LSA_HEADER_SIZE;
2928
2929 listnode_add (rm_list, lsa);
2930 }
2931
2932 /* Remove LSA from LS-Ack list. */
2933 for (node = listhead (rm_list); node; nextnode (node))
2934 {
2935 lsa = (struct ospf_lsa *) getdata (node);
2936
2937 listnode_delete (ack, lsa);
2938 ospf_lsa_unlock (lsa);
2939 }
2940
2941 list_delete (rm_list);
2942
2943 return length;
2944}
2945
2946void
2947ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2948{
2949 struct ospf_packet *op;
2950 u_int16_t length = OSPF_HEADER_SIZE;
2951
2952 op = ospf_packet_new (oi->ifp->mtu);
2953
2954 /* Prepare OSPF common header. */
2955 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2956
2957 /* Prepare OSPF Hello body. */
2958 length += ospf_make_hello (oi, op->s);
2959
2960 /* Fill OSPF header. */
2961 ospf_fill_header (oi, op->s, length);
2962
2963 /* Set packet length. */
2964 op->length = length;
2965
2966 op->dst.s_addr = addr->s_addr;
2967
2968 /* Add packet to the interface output queue. */
2969 ospf_packet_add (oi, op);
2970
2971 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002972 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002973}
2974
2975void
2976ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2977{
2978 struct ospf_interface *oi;
2979
2980 oi = nbr_nbma->oi;
2981 assert(oi);
2982
2983 /* If this is passive interface, do not send OSPF Hello. */
2984 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2985 return;
2986
2987 if (oi->type != OSPF_IFTYPE_NBMA)
2988 return;
2989
2990 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2991 return;
2992
2993 if (PRIORITY(oi) == 0)
2994 return;
2995
2996 if (nbr_nbma->priority == 0
2997 && oi->state != ISM_DR && oi->state != ISM_Backup)
2998 return;
2999
3000 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3001}
3002
3003int
3004ospf_poll_timer (struct thread *thread)
3005{
3006 struct ospf_nbr_nbma *nbr_nbma;
3007
3008 nbr_nbma = THREAD_ARG (thread);
3009 nbr_nbma->t_poll = NULL;
3010
3011 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003012 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003013 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3014
3015 ospf_poll_send (nbr_nbma);
3016
3017 if (nbr_nbma->v_poll > 0)
3018 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3019 nbr_nbma->v_poll);
3020
3021 return 0;
3022}
3023
3024
3025int
3026ospf_hello_reply_timer (struct thread *thread)
3027{
3028 struct ospf_neighbor *nbr;
3029
3030 nbr = THREAD_ARG (thread);
3031 nbr->t_hello_reply = NULL;
3032
3033 assert (nbr->oi);
3034
3035 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003036 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003037 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3038
3039 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3040
3041 return 0;
3042}
3043
3044/* Send OSPF Hello. */
3045void
3046ospf_hello_send (struct ospf_interface *oi)
3047{
3048 struct ospf_packet *op;
3049 u_int16_t length = OSPF_HEADER_SIZE;
3050
3051 /* If this is passive interface, do not send OSPF Hello. */
3052 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3053 return;
3054
3055 op = ospf_packet_new (oi->ifp->mtu);
3056
3057 /* Prepare OSPF common header. */
3058 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3059
3060 /* Prepare OSPF Hello body. */
3061 length += ospf_make_hello (oi, op->s);
3062
3063 /* Fill OSPF header. */
3064 ospf_fill_header (oi, op->s, length);
3065
3066 /* Set packet length. */
3067 op->length = length;
3068
3069 if (oi->type == OSPF_IFTYPE_NBMA)
3070 {
3071 struct ospf_neighbor *nbr;
3072 struct route_node *rn;
3073
3074 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3075 if ((nbr = rn->info))
3076 if (nbr != oi->nbr_self)
3077 if (nbr->state != NSM_Down)
3078 {
3079 /* RFC 2328 Section 9.5.1
3080 If the router is not eligible to become Designated Router,
3081 it must periodically send Hello Packets to both the
3082 Designated Router and the Backup Designated Router (if they
3083 exist). */
3084 if (PRIORITY(oi) == 0 &&
3085 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3086 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3087 continue;
3088
3089 /* If the router is eligible to become Designated Router, it
3090 must periodically send Hello Packets to all neighbors that
3091 are also eligible. In addition, if the router is itself the
3092 Designated Router or Backup Designated Router, it must also
3093 send periodic Hello Packets to all other neighbors. */
3094
3095 if (nbr->priority == 0 && oi->state == ISM_DROther)
3096 continue;
3097 /* if oi->state == Waiting, send hello to all neighbors */
3098 {
3099 struct ospf_packet *op_dup;
3100
3101 op_dup = ospf_packet_dup(op);
3102 op_dup->dst = nbr->address.u.prefix4;
3103
3104 /* Add packet to the interface output queue. */
3105 ospf_packet_add (oi, op_dup);
3106
paul020709f2003-04-04 02:44:16 +00003107 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003108 }
3109
3110 }
3111 ospf_packet_free (op);
3112 }
3113 else
3114 {
3115 /* Decide destination address. */
3116 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3117 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3118 else
3119 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3120
3121 /* Add packet to the interface output queue. */
3122 ospf_packet_add (oi, op);
3123
3124 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003125 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003126 }
3127}
3128
3129/* Send OSPF Database Description. */
3130void
3131ospf_db_desc_send (struct ospf_neighbor *nbr)
3132{
3133 struct ospf_interface *oi;
3134 struct ospf_packet *op;
3135 u_int16_t length = OSPF_HEADER_SIZE;
3136
3137 oi = nbr->oi;
3138 op = ospf_packet_new (oi->ifp->mtu);
3139
3140 /* Prepare OSPF common header. */
3141 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3142
3143 /* Prepare OSPF Database Description body. */
3144 length += ospf_make_db_desc (oi, nbr, op->s);
3145
3146 /* Fill OSPF header. */
3147 ospf_fill_header (oi, op->s, length);
3148
3149 /* Set packet length. */
3150 op->length = length;
3151
3152 /* Decide destination address. */
3153 op->dst = nbr->address.u.prefix4;
3154
3155 /* Add packet to the interface output queue. */
3156 ospf_packet_add (oi, op);
3157
3158 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003159 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003160
3161 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3162 if (nbr->last_send)
3163 ospf_packet_free (nbr->last_send);
3164 nbr->last_send = ospf_packet_dup (op);
3165 gettimeofday (&nbr->last_send_ts, NULL);
3166}
3167
3168/* Re-send Database Description. */
3169void
3170ospf_db_desc_resend (struct ospf_neighbor *nbr)
3171{
3172 struct ospf_interface *oi;
3173
3174 oi = nbr->oi;
3175
3176 /* Add packet to the interface output queue. */
3177 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3178
3179 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003180 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003181}
3182
3183/* Send Link State Request. */
3184void
3185ospf_ls_req_send (struct ospf_neighbor *nbr)
3186{
3187 struct ospf_interface *oi;
3188 struct ospf_packet *op;
3189 u_int16_t length = OSPF_HEADER_SIZE;
3190
3191 oi = nbr->oi;
3192 op = ospf_packet_new (oi->ifp->mtu);
3193
3194 /* Prepare OSPF common header. */
3195 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3196
3197 /* Prepare OSPF Link State Request body. */
3198 length += ospf_make_ls_req (nbr, op->s);
3199 if (length == OSPF_HEADER_SIZE)
3200 {
3201 ospf_packet_free (op);
3202 return;
3203 }
3204
3205 /* Fill OSPF header. */
3206 ospf_fill_header (oi, op->s, length);
3207
3208 /* Set packet length. */
3209 op->length = length;
3210
3211 /* Decide destination address. */
3212 op->dst = nbr->address.u.prefix4;
3213
3214 /* Add packet to the interface output queue. */
3215 ospf_packet_add (oi, op);
3216
3217 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003218 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003219
3220 /* Add Link State Request Retransmission Timer. */
3221 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3222}
3223
3224/* Send Link State Update with an LSA. */
3225void
3226ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3227 int flag)
3228{
hasso52dc7ee2004-09-23 19:18:23 +00003229 struct list *update;
paul718e3742002-12-13 20:15:29 +00003230
3231 update = list_new ();
3232
3233 listnode_add (update, lsa);
3234 ospf_ls_upd_send (nbr, update, flag);
3235
3236 list_delete (update);
3237}
3238
paul68b73392004-09-12 14:21:37 +00003239/* Determine size for packet. Must be at least big enough to accomodate next
3240 * LSA on list, which may be bigger than MTU size.
3241 *
3242 * Return pointer to new ospf_packet
3243 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3244 * on packet sizes (in which case offending LSA is deleted from update list)
3245 */
3246static struct ospf_packet *
3247ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3248{
3249 struct ospf_lsa *lsa;
3250 struct listnode *ln;
3251 size_t size;
3252 static char warned = 0;
3253
3254 ln = listhead (update);
3255 lsa = getdata (ln);
3256 assert (lsa);
3257 assert (lsa->data);
3258
3259 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3260 > ospf_packet_max (oi))
3261 {
3262 if (!warned)
3263 {
3264 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3265 "will need to fragment. Not optimal. Try divide up"
3266 " your network with areas. Use 'debug ospf packet send'"
3267 " to see details, or look at 'show ip ospf database ..'");
3268 warned = 1;
3269 }
3270
3271 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003272 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003273 " %d bytes originated by %s, will be fragmented!",
3274 inet_ntoa (lsa->data->id),
3275 ntohs (lsa->data->length),
3276 inet_ntoa (lsa->data->adv_router));
3277
3278 /*
3279 * Allocate just enough to fit this LSA only, to avoid including other
3280 * LSAs in fragmented LSA Updates.
3281 */
3282 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3283 + OSPF_LS_UPD_MIN_SIZE;
3284 }
3285 else
3286 size = oi->ifp->mtu;
3287
gdt86f1fd92005-01-10 14:20:43 +00003288 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003289 if (size > OSPF_MAX_PACKET_SIZE)
3290 {
3291 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003292 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003293 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003294 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003295 (long int) size);
paul68b73392004-09-12 14:21:37 +00003296 list_delete_node (update, ln);
3297 return NULL;
3298 }
3299
3300 return ospf_packet_new (size);
3301}
3302
paul718e3742002-12-13 20:15:29 +00003303static void
hasso52dc7ee2004-09-23 19:18:23 +00003304ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003305 struct in_addr addr)
3306{
3307 struct ospf_packet *op;
3308 u_int16_t length = OSPF_HEADER_SIZE;
3309
3310 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003311 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003312
3313 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003314
3315 /* Prepare OSPF common header. */
3316 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3317
paul59ea14c2004-07-14 20:50:36 +00003318 /* Prepare OSPF Link State Update body.
3319 * Includes Type-7 translation.
3320 */
paul718e3742002-12-13 20:15:29 +00003321 length += ospf_make_ls_upd (oi, update, op->s);
3322
3323 /* Fill OSPF header. */
3324 ospf_fill_header (oi, op->s, length);
3325
3326 /* Set packet length. */
3327 op->length = length;
3328
3329 /* Decide destination address. */
3330 op->dst.s_addr = addr.s_addr;
3331
3332 /* Add packet to the interface output queue. */
3333 ospf_packet_add (oi, op);
3334
3335 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003336 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003337}
3338
3339static int
3340ospf_ls_upd_send_queue_event (struct thread *thread)
3341{
3342 struct ospf_interface *oi = THREAD_ARG(thread);
3343 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003344 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003345 struct list *update;
paul68b73392004-09-12 14:21:37 +00003346 char again = 0;
paul718e3742002-12-13 20:15:29 +00003347
3348 oi->t_ls_upd_event = NULL;
3349
3350 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003351 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003352
paul736d3442003-07-24 23:22:57 +00003353 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003354 {
paul736d3442003-07-24 23:22:57 +00003355 rnext = route_next (rn);
3356
paul718e3742002-12-13 20:15:29 +00003357 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003358 continue;
paul68b73392004-09-12 14:21:37 +00003359
3360 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003361
paul48fe13b2004-07-27 17:40:44 +00003362 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003363
paul68b73392004-09-12 14:21:37 +00003364 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003365 if (listcount(update) == 0)
3366 {
3367 list_delete (rn->info);
3368 rn->info = NULL;
3369 route_unlock_node (rn);
3370 }
3371 else
paul68b73392004-09-12 14:21:37 +00003372 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003373 }
3374
3375 if (again != 0)
3376 {
3377 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003378 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003379 " %d nodes to try again, raising new event", again);
3380 oi->t_ls_upd_event =
3381 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003382 }
3383
3384 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003385 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003386
paul718e3742002-12-13 20:15:29 +00003387 return 0;
3388}
3389
3390void
hasso52dc7ee2004-09-23 19:18:23 +00003391ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003392{
3393 struct ospf_interface *oi;
3394 struct prefix_ipv4 p;
3395 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003396 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003397
3398 oi = nbr->oi;
3399
3400 p.family = AF_INET;
3401 p.prefixlen = IPV4_MAX_BITLEN;
3402
3403 /* Decide destination address. */
3404 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3405 p.prefix = oi->vl_data->peer_addr;
3406 else if (flag == OSPF_SEND_PACKET_DIRECT)
3407 p.prefix = nbr->address.u.prefix4;
3408 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3409 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3410 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3411 && (flag == OSPF_SEND_PACKET_INDIRECT))
3412 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003413 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3414 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003415 else
3416 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3417
3418 if (oi->type == OSPF_IFTYPE_NBMA)
3419 {
3420 if (flag == OSPF_SEND_PACKET_INDIRECT)
3421 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3422 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3423 zlog_warn ("* LS-Update is sent to myself.");
3424 }
3425
3426 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3427
3428 if (rn->info == NULL)
3429 rn->info = list_new ();
3430
3431 for (n = listhead (update); n; nextnode (n))
3432 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3433
3434 if (oi->t_ls_upd_event == NULL)
3435 oi->t_ls_upd_event =
3436 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3437}
3438
3439static void
hasso52dc7ee2004-09-23 19:18:23 +00003440ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3441 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003442{
3443 struct ospf_packet *op;
3444 u_int16_t length = OSPF_HEADER_SIZE;
3445
3446 op = ospf_packet_new (oi->ifp->mtu);
3447
3448 /* Prepare OSPF common header. */
3449 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3450
3451 /* Prepare OSPF Link State Acknowledgment body. */
3452 length += ospf_make_ls_ack (oi, ack, op->s);
3453
3454 /* Fill OSPF header. */
3455 ospf_fill_header (oi, op->s, length);
3456
3457 /* Set packet length. */
3458 op->length = length;
3459
3460 /* Set destination IP address. */
3461 op->dst = dst;
3462
3463 /* Add packet to the interface output queue. */
3464 ospf_packet_add (oi, op);
3465
3466 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003467 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003468}
3469
3470static int
3471ospf_ls_ack_send_event (struct thread *thread)
3472{
3473 struct ospf_interface *oi = THREAD_ARG (thread);
3474
3475 oi->t_ls_ack_direct = NULL;
3476
3477 while (listcount (oi->ls_ack_direct.ls_ack))
3478 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3479 oi->ls_ack_direct.dst);
3480
3481 return 0;
3482}
3483
3484void
3485ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3486{
3487 struct ospf_interface *oi = nbr->oi;
3488
3489 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3490 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3491
3492 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3493
3494 if (oi->t_ls_ack_direct == NULL)
3495 oi->t_ls_ack_direct =
3496 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3497}
3498
3499/* Send Link State Acknowledgment delayed. */
3500void
3501ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3502{
3503 struct in_addr dst;
3504
3505 /* Decide destination address. */
3506 /* RFC2328 Section 13.5 On non-broadcast
3507 networks, delayed Link State Acknowledgment packets must be
3508 unicast separately over each adjacency (i.e., neighbor whose
3509 state is >= Exchange). */
3510 if (oi->type == OSPF_IFTYPE_NBMA)
3511 {
3512 struct ospf_neighbor *nbr;
3513 struct route_node *rn;
3514
3515 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3516 if ((nbr = rn->info) != NULL)
3517 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3518 while (listcount (oi->ls_ack))
3519 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3520 return;
3521 }
3522 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3523 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3524 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3525 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3526 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3527 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003528 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3529 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003530 else
3531 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3532
3533 while (listcount (oi->ls_ack))
3534 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3535}