blob: 44b130b76fbb5e9cdf8154e77e51db1af6d7f61f [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Sending and Receiving OSPF Packets.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "memory.h"
27#include "linklist.h"
28#include "prefix.h"
29#include "if.h"
30#include "table.h"
31#include "sockunion.h"
32#include "stream.h"
33#include "log.h"
paul2dd8bb42004-07-23 15:13:48 +000034#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000035#include "md5-gnu.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_flood.h"
49#include "ospfd/ospf_dump.h"
50
hasso52dc7ee2004-09-23 19:18:23 +000051static void ospf_ls_ack_send_list (struct ospf_interface *, struct list *,
paul718e3742002-12-13 20:15:29 +000052 struct in_addr);
53
54/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000055const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000056{
57 "unknown",
58 "Hello",
59 "Database Description",
60 "Link State Request",
61 "Link State Update",
62 "Link State Acknowledgment",
63};
64
65extern int in_cksum (void *ptr, int nbytes);
66
67/* OSPF authentication checking function */
68int
69ospf_auth_type (struct ospf_interface *oi)
70{
71 int auth_type;
72
73 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
74 auth_type = oi->area->auth_type;
75 else
76 auth_type = OSPF_IF_PARAM (oi, auth_type);
77
78 /* Handle case where MD5 key list is not configured aka Cisco */
79 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
80 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
81 return OSPF_AUTH_NULL;
82
83 return auth_type;
84
85}
86
87/* forward output pointer. */
88void
89ospf_output_forward (struct stream *s, int size)
90{
91 s->putp += size;
92}
93
94struct ospf_packet *
95ospf_packet_new (size_t size)
96{
97 struct ospf_packet *new;
98
99 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
100 new->s = stream_new (size);
101
102 return new;
103}
104
105void
106ospf_packet_free (struct ospf_packet *op)
107{
108 if (op->s)
109 stream_free (op->s);
110
111 XFREE (MTYPE_OSPF_PACKET, op);
112
113 op = NULL;
114}
115
116struct ospf_fifo *
117ospf_fifo_new ()
118{
119 struct ospf_fifo *new;
120
121 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
122 return new;
123}
124
125/* Add new packet to fifo. */
126void
127ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
128{
129 if (fifo->tail)
130 fifo->tail->next = op;
131 else
132 fifo->head = op;
133
134 fifo->tail = op;
135
136 fifo->count++;
137}
138
139/* Delete first packet from fifo. */
140struct ospf_packet *
141ospf_fifo_pop (struct ospf_fifo *fifo)
142{
143 struct ospf_packet *op;
144
145 op = fifo->head;
146
147 if (op)
148 {
149 fifo->head = op->next;
150
151 if (fifo->head == NULL)
152 fifo->tail = NULL;
153
154 fifo->count--;
155 }
156
157 return op;
158}
159
160/* Return first fifo entry. */
161struct ospf_packet *
162ospf_fifo_head (struct ospf_fifo *fifo)
163{
164 return fifo->head;
165}
166
167/* Flush ospf packet fifo. */
168void
169ospf_fifo_flush (struct ospf_fifo *fifo)
170{
171 struct ospf_packet *op;
172 struct ospf_packet *next;
173
174 for (op = fifo->head; op; op = next)
175 {
176 next = op->next;
177 ospf_packet_free (op);
178 }
179 fifo->head = fifo->tail = NULL;
180 fifo->count = 0;
181}
182
183/* Free ospf packet fifo. */
184void
185ospf_fifo_free (struct ospf_fifo *fifo)
186{
187 ospf_fifo_flush (fifo);
188
189 XFREE (MTYPE_OSPF_FIFO, fifo);
190}
191
192void
193ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
194{
ajsc3eab872005-01-29 15:52:07 +0000195 if (!oi->obuf)
196 {
197 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
198 "destination %s) called with NULL obuf, ignoring "
199 "(please report this bug)!\n",
200 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
201 ospf_packet_type_str[stream_getc_from(op->s, 1)],
202 inet_ntoa (op->dst));
203 return;
204 }
205
paul718e3742002-12-13 20:15:29 +0000206 /* Add packet to end of queue. */
207 ospf_fifo_push (oi->obuf, op);
208
209 /* Debug of packet fifo*/
210 /* ospf_fifo_debug (oi->obuf); */
211}
212
213void
214ospf_packet_delete (struct ospf_interface *oi)
215{
216 struct ospf_packet *op;
217
218 op = ospf_fifo_pop (oi->obuf);
219
220 if (op)
221 ospf_packet_free (op);
222}
223
224struct stream *
225ospf_stream_copy (struct stream *new, struct stream *s)
226{
227 new->endp = s->endp;
228 new->putp = s->putp;
229 new->getp = s->getp;
230
231 memcpy (new->data, s->data, stream_get_endp (s));
232
233 return new;
234}
235
236struct ospf_packet *
237ospf_packet_dup (struct ospf_packet *op)
238{
239 struct ospf_packet *new;
240
paul37163d62003-02-03 18:40:56 +0000241 if (stream_get_endp(op->s) != op->length)
242 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000243 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000244
245 /* Reserve space for MD5 authentication that may be added later. */
246 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000247 ospf_stream_copy (new->s, op->s);
248
249 new->dst = op->dst;
250 new->length = op->length;
251
252 return new;
253}
254
gdt86f1fd92005-01-10 14:20:43 +0000255/* XXX inline */
256unsigned int
257ospf_packet_authspace (struct ospf_interface *oi)
258{
259 int auth = 0;
260
261 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
262 auth = OSPF_AUTH_MD5_SIZE;
263
264 return auth;
265}
266
paul6c835672004-10-11 11:00:30 +0000267unsigned int
paul718e3742002-12-13 20:15:29 +0000268ospf_packet_max (struct ospf_interface *oi)
269{
270 int max;
271
gdt86f1fd92005-01-10 14:20:43 +0000272 max = oi->ifp->mtu - ospf_packet_authspace(oi);
273
paul68b73392004-09-12 14:21:37 +0000274 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000275
276 return max;
277}
278
279
280int
281ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
282 u_int16_t length)
283{
paul6c835672004-10-11 11:00:30 +0000284 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000285 struct md5_ctx ctx;
286 unsigned char digest[OSPF_AUTH_MD5_SIZE];
287 unsigned char *pdigest;
288 struct crypt_key *ck;
289 struct ospf_header *ospfh;
290 struct ospf_neighbor *nbr;
291
292
293 ibuf = STREAM_PNT (s);
294 ospfh = (struct ospf_header *) ibuf;
295
296 /* Get pointer to the end of the packet. */
297 pdigest = ibuf + length;
298
299 /* Get secret key. */
300 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
301 ospfh->u.crypt.key_id);
302 if (ck == NULL)
303 {
304 zlog_warn ("interface %s: ospf_check_md5 no key %d",
305 IF_NAME (oi), ospfh->u.crypt.key_id);
306 return 0;
307 }
308
309 /* check crypto seqnum. */
310 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
311
312 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
313 {
314 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
315 IF_NAME (oi),
316 ntohl(ospfh->u.crypt.crypt_seqnum),
317 ntohl(nbr->crypt_seqnum));
318 return 0;
319 }
320
321 /* Generate a digest for the ospf packet - their digest + our digest. */
322 md5_init_ctx (&ctx);
323 md5_process_bytes (ibuf, length, &ctx);
324 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
325 md5_finish_ctx (&ctx, digest);
326
327 /* compare the two */
328 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
329 {
330 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
331 IF_NAME (oi));
332 return 0;
333 }
334
335 /* save neighbor's crypt_seqnum */
336 if (nbr)
337 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
338 return 1;
339}
340
341/* This function is called from ospf_write(), it will detect the
342 authentication scheme and if it is MD5, it will change the sequence
343 and update the MD5 digest. */
344int
345ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
346{
347 struct ospf_header *ospfh;
348 unsigned char digest[OSPF_AUTH_MD5_SIZE];
349 struct md5_ctx ctx;
350 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000351 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000352 struct crypt_key *ck;
353 char *auth_key;
354
355 ibuf = STREAM_DATA (op->s);
356 ospfh = (struct ospf_header *) ibuf;
357
358 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
359 return 0;
360
361 /* We do this here so when we dup a packet, we don't have to
362 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000363 t = (time(NULL) & 0xFFFFFFFF);
364 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
365 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000366
367 /* Get MD5 Authentication key from auth_key list. */
368 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000369 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000370 else
371 {
372 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000373 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000374 }
375
376 /* Generate a digest for the entire packet + our secret key. */
377 md5_init_ctx (&ctx);
378 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
379 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
380 md5_finish_ctx (&ctx, digest);
381
382 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000383 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000384
385 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000386 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
387
paul37163d62003-02-03 18:40:56 +0000388 if (stream_get_endp(op->s) != op->length)
389 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 +0000390
391 return OSPF_AUTH_MD5_SIZE;
392}
393
394
395int
396ospf_ls_req_timer (struct thread *thread)
397{
398 struct ospf_neighbor *nbr;
399
400 nbr = THREAD_ARG (thread);
401 nbr->t_ls_req = NULL;
402
403 /* Send Link State Request. */
404 if (ospf_ls_request_count (nbr))
405 ospf_ls_req_send (nbr);
406
407 /* Set Link State Request retransmission timer. */
408 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
409
410 return 0;
411}
412
413void
414ospf_ls_req_event (struct ospf_neighbor *nbr)
415{
416 if (nbr->t_ls_req)
417 {
418 thread_cancel (nbr->t_ls_req);
419 nbr->t_ls_req = NULL;
420 }
421 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
422}
423
424/* Cyclic timer function. Fist registered in ospf_nbr_new () in
425 ospf_neighbor.c */
426int
427ospf_ls_upd_timer (struct thread *thread)
428{
429 struct ospf_neighbor *nbr;
430
431 nbr = THREAD_ARG (thread);
432 nbr->t_ls_upd = NULL;
433
434 /* Send Link State Update. */
435 if (ospf_ls_retransmit_count (nbr) > 0)
436 {
hasso52dc7ee2004-09-23 19:18:23 +0000437 struct list *update;
paul718e3742002-12-13 20:15:29 +0000438 struct ospf_lsdb *lsdb;
439 int i;
440 struct timeval now;
441 int retransmit_interval;
442
443 gettimeofday (&now, NULL);
444 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
445
446 lsdb = &nbr->ls_rxmt;
447 update = list_new ();
448
449 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
450 {
451 struct route_table *table = lsdb->type[i].db;
452 struct route_node *rn;
453
454 for (rn = route_top (table); rn; rn = route_next (rn))
455 {
456 struct ospf_lsa *lsa;
457
458 if ((lsa = rn->info) != NULL)
459 /* Don't retransmit an LSA if we received it within
460 the last RxmtInterval seconds - this is to allow the
461 neighbour a chance to acknowledge the LSA as it may
462 have ben just received before the retransmit timer
463 fired. This is a small tweak to what is in the RFC,
464 but it will cut out out a lot of retransmit traffic
465 - MAG */
466 if (tv_cmp (tv_sub (now, lsa->tv_recv),
467 int2tv (retransmit_interval)) >= 0)
468 listnode_add (update, rn->info);
469 }
470 }
471
472 if (listcount (update) > 0)
473 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
474 list_delete (update);
475 }
476
477 /* Set LS Update retransmission timer. */
478 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
479
480 return 0;
481}
482
483int
484ospf_ls_ack_timer (struct thread *thread)
485{
486 struct ospf_interface *oi;
487
488 oi = THREAD_ARG (thread);
489 oi->t_ls_ack = NULL;
490
491 /* Send Link State Acknowledgment. */
492 if (listcount (oi->ls_ack) > 0)
493 ospf_ls_ack_send_delayed (oi);
494
495 /* Set LS Ack timer. */
496 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
497
498 return 0;
499}
500
paul0bfeca32004-09-24 08:07:54 +0000501#ifdef WANT_OSPF_WRITE_FRAGMENT
502void
paul6a99f832004-09-27 12:56:30 +0000503ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000504 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000505 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000506{
507#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000508 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000509 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000510 int ret;
paul0bfeca32004-09-24 08:07:54 +0000511
512 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000513 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000514
515 /* we can but try.
516 *
517 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
518 * well as the IP_MF flag, making this all quite pointless.
519 *
520 * However, for a system on which IP_MF is left alone, and ip_id left
521 * alone or else which sets same ip_id for each fragment this might
522 * work, eg linux.
523 *
524 * XXX-TODO: It would be much nicer to have the kernel's use their
525 * existing fragmentation support to do this for us. Bugs/RFEs need to
526 * be raised against the various kernels.
527 */
528
529 /* set More Frag */
530 iph->ip_off |= IP_MF;
531
532 /* ip frag offset is expressed in units of 8byte words */
533 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
534
paul62d8e962004-11-02 20:26:45 +0000535 iovp = &msg->msg_iov[1];
536
paul0bfeca32004-09-24 08:07:54 +0000537 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
538 > maxdatasize )
539 {
540 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000541 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
542 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000543 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000544
paul18b12c32004-10-05 14:38:29 +0000545 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000546
paul6a99f832004-09-27 12:56:30 +0000547 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000548
paul18b12c32004-10-05 14:38:29 +0000549 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000550
551 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000552 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000553 " id %d, off %d, len %d failed with %s",
554 inet_ntoa (iph->ip_dst),
555 iph->ip_id,
556 iph->ip_off,
557 iph->ip_len,
ajs6099b3b2004-11-20 02:06:59 +0000558 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000559
paul37ccfa32004-10-31 11:24:51 +0000560 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
561 {
ajs2a42e282004-12-08 18:43:03 +0000562 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000563 iph->ip_id, iph->ip_off, iph->ip_len,
564 inet_ntoa (iph->ip_dst));
565 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
566 {
ajs2a42e282004-12-08 18:43:03 +0000567 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000568 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000569 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000570 }
571 }
572
paul0bfeca32004-09-24 08:07:54 +0000573 iph->ip_off += offset;
paul62d8e962004-11-02 20:26:45 +0000574 stream_forward (op->s, iovp->iov_len);
575 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000576 }
577
578 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000579 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
580 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000581 iph->ip_off &= (~IP_MF);
582}
583#endif /* WANT_OSPF_WRITE_FRAGMENT */
584
paul718e3742002-12-13 20:15:29 +0000585int
586ospf_write (struct thread *thread)
587{
paul68980082003-03-25 05:07:42 +0000588 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000589 struct ospf_interface *oi;
590 struct ospf_packet *op;
591 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000592 struct ip iph;
593 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000594 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000595 u_char type;
596 int ret;
597 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000598 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000599#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000600 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000601#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000602 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000603#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000604
paul68980082003-03-25 05:07:42 +0000605 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000606
paul68980082003-03-25 05:07:42 +0000607 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000608 assert (node);
609 oi = getdata (node);
610 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000611
612#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000613 /* seed ipid static with low order bits of time */
614 if (ipid == 0)
615 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000616#endif /* WANT_OSPF_WRITE_FRAGMENT */
617
paul68b73392004-09-12 14:21:37 +0000618 /* convenience - max OSPF data per packet */
619 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
620
paul718e3742002-12-13 20:15:29 +0000621 /* Get one packet from queue. */
622 op = ospf_fifo_head (oi->obuf);
623 assert (op);
624 assert (op->length >= OSPF_HEADER_SIZE);
625
paul68980082003-03-25 05:07:42 +0000626 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
627 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000628 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
629
paul718e3742002-12-13 20:15:29 +0000630 /* Rewrite the md5 signature & update the seq */
631 ospf_make_md5_digest (oi, op);
632
paul37ccfa32004-10-31 11:24:51 +0000633 /* Retrieve OSPF packet type. */
634 stream_set_getp (op->s, 1);
635 type = stream_getc (op->s);
636
paul68b73392004-09-12 14:21:37 +0000637 /* reset get pointer */
638 stream_set_getp (op->s, 0);
639
640 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000641 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000642
paul718e3742002-12-13 20:15:29 +0000643 sa_dst.sin_family = AF_INET;
644#ifdef HAVE_SIN_LEN
645 sa_dst.sin_len = sizeof(sa_dst);
646#endif /* HAVE_SIN_LEN */
647 sa_dst.sin_addr = op->dst;
648 sa_dst.sin_port = htons (0);
649
650 /* Set DONTROUTE flag if dst is unicast. */
651 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
652 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
653 flags = MSG_DONTROUTE;
654
paul68b73392004-09-12 14:21:37 +0000655 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
656 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000657 if ( sizeof (struct ip)
658 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000659 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
660
paul718e3742002-12-13 20:15:29 +0000661 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000662 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000663 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000664
paul0bfeca32004-09-24 08:07:54 +0000665#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000666 /* XXX-MT: not thread-safe at all..
667 * XXX: this presumes this is only programme sending OSPF packets
668 * otherwise, no guarantee ipid will be unique
669 */
670 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000671#endif /* WANT_OSPF_WRITE_FRAGMENT */
672
paul718e3742002-12-13 20:15:29 +0000673 iph.ip_off = 0;
674 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
675 iph.ip_ttl = OSPF_VL_IP_TTL;
676 else
677 iph.ip_ttl = OSPF_IP_TTL;
678 iph.ip_p = IPPROTO_OSPFIGP;
679 iph.ip_sum = 0;
680 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
681 iph.ip_dst.s_addr = op->dst.s_addr;
682
683 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000684 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000685 msg.msg_namelen = sizeof (sa_dst);
686 msg.msg_iov = iov;
687 msg.msg_iovlen = 2;
688 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000689 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
690 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000691 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000692
693 /* Sadly we can not rely on kernels to fragment packets because of either
694 * IP_HDRINCL and/or multicast destination being set.
695 */
paul0bfeca32004-09-24 08:07:54 +0000696#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000697 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000698 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
699 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000700#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000701
702 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000703 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000704 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000705 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000706
707 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000708 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
709 "id %d, off %d, len %d: %s",
710 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
711 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000712
paul718e3742002-12-13 20:15:29 +0000713 /* Show debug sending packet. */
714 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
715 {
716 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
717 {
ajs2a42e282004-12-08 18:43:03 +0000718 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000719 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000720 stream_set_getp (op->s, 0);
721 ospf_packet_dump (op->s);
722 }
723
ajs2a42e282004-12-08 18:43:03 +0000724 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000725 ospf_packet_type_str[type], inet_ntoa (op->dst),
726 IF_NAME (oi));
727
728 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000729 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000730 }
731
732 /* Now delete packet from queue. */
733 ospf_packet_delete (oi);
734
735 if (ospf_fifo_head (oi->obuf) == NULL)
736 {
737 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000738 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000739 }
740
741 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000742 if (!list_isempty (ospf->oi_write_q))
743 ospf->t_write =
744 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000745
746 return 0;
747}
748
749/* OSPF Hello message read -- RFC2328 Section 10.5. */
750void
751ospf_hello (struct ip *iph, struct ospf_header *ospfh,
752 struct stream * s, struct ospf_interface *oi, int size)
753{
754 struct ospf_hello *hello;
755 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000756 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000757 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000758
759 /* increment statistics. */
760 oi->hello_in++;
761
762 hello = (struct ospf_hello *) STREAM_PNT (s);
763
764 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000765 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000766 {
767 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
768 {
ajs2a42e282004-12-08 18:43:03 +0000769 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000770 "dropping.",
771 ospf_packet_type_str[ospfh->type],
772 inet_ntoa (iph->ip_src));
773 }
774 return;
775 }
paul718e3742002-12-13 20:15:29 +0000776
777 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000778 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000779 char buf[3][INET_ADDRSTRLEN];
780 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
781 "should not receive hellos on passive interface %s!",
782 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
783 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
784 inet_ntop(AF_INET, &oi->address->u.prefix4,
785 buf[2], sizeof(buf[2])));
786 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
787 {
788 /* Try to fix multicast membership. */
789 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
790 ospf_if_set_multicast(oi);
791 }
paul718e3742002-12-13 20:15:29 +0000792 return;
paulf2c80652002-12-13 21:44:27 +0000793 }
paul718e3742002-12-13 20:15:29 +0000794
795 /* get neighbor prefix. */
796 p.family = AF_INET;
797 p.prefixlen = ip_masklen (hello->network_mask);
798 p.u.prefix4 = iph->ip_src;
799
800 /* Compare network mask. */
801 /* Checking is ignored for Point-to-Point and Virtual link. */
802 if (oi->type != OSPF_IFTYPE_POINTOPOINT
803 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
804 if (oi->address->prefixlen != p.prefixlen)
805 {
806 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
807 inet_ntoa (ospfh->router_id));
808 return;
809 }
810
811 /* Compare Hello Interval. */
812 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
813 {
814 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
815 inet_ntoa (ospfh->router_id));
816 return;
817 }
818
819 /* Compare Router Dead Interval. */
820 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
821 {
822 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
823 inet_ntoa (ospfh->router_id));
824 return;
825 }
826
827 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000828 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000829 inet_ntoa (ospfh->router_id),
830 ospf_options_dump (hello->options));
831
832 /* Compare options. */
833#define REJECT_IF_TBIT_ON 1 /* XXX */
834#ifdef REJECT_IF_TBIT_ON
835 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
836 {
837 /*
838 * This router does not support non-zero TOS.
839 * Drop this Hello packet not to establish neighbor relationship.
840 */
841 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
842 inet_ntoa (ospfh->router_id));
843 return;
844 }
845#endif /* REJECT_IF_TBIT_ON */
846
847#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000848 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000849 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
850 {
851 /*
852 * This router does know the correct usage of O-bit
853 * the bit should be set in DD packet only.
854 */
855 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
856 inet_ntoa (ospfh->router_id));
857#ifdef STRICT_OBIT_USAGE_CHECK
858 return; /* Reject this packet. */
859#else /* STRICT_OBIT_USAGE_CHECK */
860 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
861#endif /* STRICT_OBIT_USAGE_CHECK */
862 }
863#endif /* HAVE_OPAQUE_LSA */
864
865 /* new for NSSA is to ensure that NP is on and E is off */
866
paul718e3742002-12-13 20:15:29 +0000867 if (oi->area->external_routing == OSPF_AREA_NSSA)
868 {
869 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
870 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
871 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
872 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
873 {
874 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
875 return;
876 }
877 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000878 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000879 }
880 else
paul718e3742002-12-13 20:15:29 +0000881 /* The setting of the E-bit found in the Hello Packet's Options
882 field must match this area's ExternalRoutingCapability A
883 mismatch causes processing to stop and the packet to be
884 dropped. The setting of the rest of the bits in the Hello
885 Packet's Options field should be ignored. */
886 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
887 CHECK_FLAG (hello->options, OSPF_OPTION_E))
888 {
ajs3aa8d5f2004-12-11 18:00:06 +0000889 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
890 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000891 return;
892 }
paul718e3742002-12-13 20:15:29 +0000893
pauld3f0d622004-05-05 15:27:15 +0000894 /* get neighbour struct */
895 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
896
897 /* neighbour must be valid, ospf_nbr_get creates if none existed */
898 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000899
900 old_state = nbr->state;
901
902 /* Add event to thread. */
903 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
904
905 /* RFC2328 Section 9.5.1
906 If the router is not eligible to become Designated Router,
907 (snip) It must also send an Hello Packet in reply to an
908 Hello Packet received from any eligible neighbor (other than
909 the current Designated Router and Backup Designated Router). */
910 if (oi->type == OSPF_IFTYPE_NBMA)
911 if (PRIORITY(oi) == 0 && hello->priority > 0
912 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
913 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
914 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
915 OSPF_HELLO_REPLY_DELAY);
916
917 /* on NBMA network type, it happens to receive bidirectional Hello packet
918 without advance 1-Way Received event.
919 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
920 if (oi->type == OSPF_IFTYPE_NBMA &&
921 (old_state == NSM_Down || old_state == NSM_Attempt))
922 {
923 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
924 nbr->priority = hello->priority;
925 nbr->d_router = hello->d_router;
926 nbr->bd_router = hello->bd_router;
927 return;
928 }
929
paul68980082003-03-25 05:07:42 +0000930 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000931 size - OSPF_HELLO_MIN_SIZE))
932 {
933 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
934 nbr->options |= hello->options;
935 }
936 else
937 {
938 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
939 /* Set neighbor information. */
940 nbr->priority = hello->priority;
941 nbr->d_router = hello->d_router;
942 nbr->bd_router = hello->bd_router;
943 return;
944 }
945
946 /* If neighbor itself declares DR and no BDR exists,
947 cause event BackupSeen */
948 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
949 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
951
952 /* neighbor itself declares BDR. */
953 if (oi->state == ISM_Waiting &&
954 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
955 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
956
957 /* had not previously. */
958 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
959 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
960 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
961 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
962 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
963
964 /* had not previously. */
965 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
966 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
967 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
968 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
969 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
970
971 /* Neighbor priority check. */
972 if (nbr->priority >= 0 && nbr->priority != hello->priority)
973 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
974
975 /* Set neighbor information. */
976 nbr->priority = hello->priority;
977 nbr->d_router = hello->d_router;
978 nbr->bd_router = hello->bd_router;
979}
980
981/* Save DD flags/options/Seqnum received. */
982void
983ospf_db_desc_save_current (struct ospf_neighbor *nbr,
984 struct ospf_db_desc *dd)
985{
986 nbr->last_recv.flags = dd->flags;
987 nbr->last_recv.options = dd->options;
988 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
989}
990
991/* Process rest of DD packet. */
992static void
993ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
994 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
995 u_int16_t size)
996{
997 struct ospf_lsa *new, *find;
998 struct lsa_header *lsah;
999
1000 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
1001 for (size -= OSPF_DB_DESC_MIN_SIZE;
1002 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1003 {
1004 lsah = (struct lsa_header *) STREAM_PNT (s);
1005 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1006
1007 /* Unknown LS type. */
1008 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1009 {
ajsbec595a2004-11-30 22:38:43 +00001010 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001011 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1012 return;
1013 }
1014
1015#ifdef HAVE_OPAQUE_LSA
1016 if (IS_OPAQUE_LSA (lsah->type)
1017 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1018 {
1019 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1020 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1021 return;
1022 }
1023#endif /* HAVE_OPAQUE_LSA */
1024
1025 switch (lsah->type)
1026 {
1027 case OSPF_AS_EXTERNAL_LSA:
1028#ifdef HAVE_OPAQUE_LSA
1029 case OSPF_OPAQUE_AS_LSA:
1030#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001031 /* Check for stub area. Reject if AS-External from stub but
1032 allow if from NSSA. */
1033 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001034 {
1035 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1036 lsah->type, inet_ntoa (lsah->id),
1037 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1038 "STUB" : "NSSA");
1039 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1040 return;
1041 }
1042 break;
1043 default:
1044 break;
1045 }
1046
1047 /* Create LS-request object. */
1048 new = ospf_ls_request_new (lsah);
1049
1050 /* Lookup received LSA, then add LS request list. */
1051 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1052 if (!find || ospf_lsa_more_recent (find, new) < 0)
1053 {
1054 ospf_ls_request_add (nbr, new);
1055 ospf_lsa_discard (new);
1056 }
1057 else
1058 {
1059 /* Received LSA is not recent. */
1060 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001061 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001062 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1063 ospf_lsa_discard (new);
1064 continue;
1065 }
1066 }
1067
1068 /* Master */
1069 if (IS_SET_DD_MS (nbr->dd_flags))
1070 {
1071 nbr->dd_seqnum++;
1072 /* Entire DD packet sent. */
1073 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1074 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1075 else
1076 /* Send new DD packet. */
1077 ospf_db_desc_send (nbr);
1078 }
1079 /* Slave */
1080 else
1081 {
1082 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1083
1084 /* When master's more flags is not set. */
1085 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1086 {
1087 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1088 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1089 }
1090
ajsbec595a2004-11-30 22:38:43 +00001091 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001092 ospf_db_desc_send (nbr);
1093 }
1094
1095 /* Save received neighbor values from DD. */
1096 ospf_db_desc_save_current (nbr, dd);
1097}
1098
1099int
1100ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1101{
1102 /* Is DD duplicated? */
1103 if (dd->options == nbr->last_recv.options &&
1104 dd->flags == nbr->last_recv.flags &&
1105 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1106 return 1;
1107
1108 return 0;
1109}
1110
1111/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001112static void
paul718e3742002-12-13 20:15:29 +00001113ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1114 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1115{
1116 struct ospf_db_desc *dd;
1117 struct ospf_neighbor *nbr;
1118
1119 /* Increment statistics. */
1120 oi->db_desc_in++;
1121
1122 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001123
pauld3f0d622004-05-05 15:27:15 +00001124 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001125 if (nbr == NULL)
1126 {
1127 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1128 inet_ntoa (ospfh->router_id));
1129 return;
1130 }
1131
1132 /* Check MTU. */
1133 if (ntohs (dd->mtu) > oi->ifp->mtu)
1134 {
ajs3aa8d5f2004-12-11 18:00:06 +00001135 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1136 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1137 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001138 return;
1139 }
1140
pauld363df22003-06-19 00:26:34 +00001141 /*
1142 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1143 * required. In fact at least JunOS sends DD packets with P bit clear.
1144 * Until proper solution is developped, this hack should help.
1145 *
1146 * Update: According to the RFCs, N bit is specified /only/ for Hello
1147 * options, unfortunately its use in DD options is not specified. Hence some
1148 * implementations follow E-bit semantics and set it in DD options, and some
1149 * treat it as unspecified and hence follow the directive "default for
1150 * options is clear", ie unset.
1151 *
1152 * Reset the flag, as ospfd follows E-bit semantics.
1153 */
1154 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1155 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1156 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1157 {
1158 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001159 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001160 inet_ntoa (nbr->router_id) );
1161 SET_FLAG (dd->options, OSPF_OPTION_NP);
1162 }
pauld363df22003-06-19 00:26:34 +00001163
paul718e3742002-12-13 20:15:29 +00001164#ifdef REJECT_IF_TBIT_ON
1165 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1166 {
1167 /*
1168 * In Hello protocol, optional capability must have checked
1169 * to prevent this T-bit enabled router be my neighbor.
1170 */
1171 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1172 return;
1173 }
1174#endif /* REJECT_IF_TBIT_ON */
1175
1176#ifdef HAVE_OPAQUE_LSA
1177 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001178 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001179 {
1180 /*
1181 * This node is not configured to handle O-bit, for now.
1182 * Clear it to ignore unsupported capability proposed by neighbor.
1183 */
1184 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1185 }
1186#endif /* HAVE_OPAQUE_LSA */
1187
1188 /* Process DD packet by neighbor status. */
1189 switch (nbr->state)
1190 {
1191 case NSM_Down:
1192 case NSM_Attempt:
1193 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001194 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001195 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001196 LOOKUP (ospf_nsm_state_msg, nbr->state));
1197 break;
1198 case NSM_Init:
1199 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1200 /* If the new state is ExStart, the processing of the current
1201 packet should then continue in this new state by falling
1202 through to case ExStart below. */
1203 if (nbr->state != NSM_ExStart)
1204 break;
1205 case NSM_ExStart:
1206 /* Initial DBD */
1207 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1208 (size == OSPF_DB_DESC_MIN_SIZE))
1209 {
paul68980082003-03-25 05:07:42 +00001210 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001211 {
1212 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001213 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001214 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001215 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1216 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1217 }
1218 else
1219 {
1220 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001221 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1222 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001223 break;
1224 }
1225 }
1226 /* Ack from the Slave */
1227 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1228 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001229 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001230 {
ajs17eaa722004-12-29 21:04:48 +00001231 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001232 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001233 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1234 }
1235 else
1236 {
ajs3aa8d5f2004-12-11 18:00:06 +00001237 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1238 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001239 break;
1240 }
1241
1242 /* This is where the real Options are saved */
1243 nbr->options = dd->options;
1244
1245#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001246 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001247 {
1248 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001249 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001250 inet_ntoa (nbr->router_id),
1251 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1252
1253 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1254 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1255 {
1256 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1257 /* This situation is undesirable, but not a real error. */
1258 }
1259 }
1260#endif /* HAVE_OPAQUE_LSA */
1261
1262 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1263
1264 /* continue processing rest of packet. */
1265 ospf_db_desc_proc (s, oi, nbr, dd, size);
1266 break;
1267 case NSM_Exchange:
1268 if (ospf_db_desc_is_dup (dd, nbr))
1269 {
1270 if (IS_SET_DD_MS (nbr->dd_flags))
1271 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001272 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1273 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001274 else
1275 /* Slave: cause to retransmit the last Database Description. */
1276 {
ajs3aa8d5f2004-12-11 18:00:06 +00001277 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1278 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001279 ospf_db_desc_resend (nbr);
1280 }
1281 break;
1282 }
1283
1284 /* Otherwise DD packet should be checked. */
1285 /* Check Master/Slave bit mismatch */
1286 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1287 {
ajs3aa8d5f2004-12-11 18:00:06 +00001288 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1289 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001290 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1291 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001292 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001293 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001294 break;
1295 }
1296
1297 /* Check initialize bit is set. */
1298 if (IS_SET_DD_I (dd->flags))
1299 {
ajs3aa8d5f2004-12-11 18:00:06 +00001300 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1301 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001302 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1303 break;
1304 }
1305
1306 /* Check DD Options. */
1307 if (dd->options != nbr->options)
1308 {
1309#ifdef ORIGINAL_CODING
1310 /* Save the new options for debugging */
1311 nbr->options = dd->options;
1312#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001313 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1314 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001315 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1316 break;
1317 }
1318
1319 /* Check DD sequence number. */
1320 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1321 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1322 (!IS_SET_DD_MS (nbr->dd_flags) &&
1323 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1324 {
ajs3aa8d5f2004-12-11 18:00:06 +00001325 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1326 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001327 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1328 break;
1329 }
1330
1331 /* Continue processing rest of packet. */
1332 ospf_db_desc_proc (s, oi, nbr, dd, size);
1333 break;
1334 case NSM_Loading:
1335 case NSM_Full:
1336 if (ospf_db_desc_is_dup (dd, nbr))
1337 {
1338 if (IS_SET_DD_MS (nbr->dd_flags))
1339 {
1340 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001341 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1342 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001343 break;
1344 }
1345 else
1346 {
1347 struct timeval t, now;
1348 gettimeofday (&now, NULL);
1349 t = tv_sub (now, nbr->last_send_ts);
1350 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1351 {
1352 /* In states Loading and Full the slave must resend
1353 its last Database Description packet in response to
1354 duplicate Database Description packets received
1355 from the master. For this reason the slave must
1356 wait RouterDeadInterval seconds before freeing the
1357 last Database Description packet. Reception of a
1358 Database Description packet from the master after
1359 this interval will generate a SeqNumberMismatch
1360 neighbor event. RFC2328 Section 10.8 */
1361 ospf_db_desc_resend (nbr);
1362 break;
1363 }
1364 }
1365 }
1366
1367 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1368 break;
1369 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001370 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1371 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001372 break;
1373 }
1374}
1375
1376#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1377
1378/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1379void
1380ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1381 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1382{
1383 struct ospf_neighbor *nbr;
1384 u_int32_t ls_type;
1385 struct in_addr ls_id;
1386 struct in_addr adv_router;
1387 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001388 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001389 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001390
1391 /* Increment statistics. */
1392 oi->ls_req_in++;
1393
pauld3f0d622004-05-05 15:27:15 +00001394 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001395 if (nbr == NULL)
1396 {
1397 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1398 inet_ntoa (ospfh->router_id));
1399 return;
1400 }
1401
1402 /* Neighbor State should be Exchange or later. */
1403 if (nbr->state != NSM_Exchange &&
1404 nbr->state != NSM_Loading &&
1405 nbr->state != NSM_Full)
1406 {
ajsbec595a2004-11-30 22:38:43 +00001407 zlog_warn ("Link State Request received from %s: "
1408 "Neighbor state is %s, packet discarded.",
1409 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001410 LOOKUP (ospf_nsm_state_msg, nbr->state));
1411 return;
1412 }
1413
1414 /* Send Link State Update for ALL requested LSAs. */
1415 ls_upd = list_new ();
1416 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1417
1418 while (size >= OSPF_LSA_KEY_SIZE)
1419 {
1420 /* Get one slice of Link State Request. */
1421 ls_type = stream_getl (s);
1422 ls_id.s_addr = stream_get_ipv4 (s);
1423 adv_router.s_addr = stream_get_ipv4 (s);
1424
1425 /* Verify LSA type. */
1426 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1427 {
1428 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1429 list_delete (ls_upd);
1430 return;
1431 }
1432
1433 /* Search proper LSA in LSDB. */
1434 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1435 if (find == NULL)
1436 {
1437 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1438 list_delete (ls_upd);
1439 return;
1440 }
1441
gdt86f1fd92005-01-10 14:20:43 +00001442 /* Packet overflows MTU size, send immediately. */
1443 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001444 {
1445 if (oi->type == OSPF_IFTYPE_NBMA)
1446 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1447 else
1448 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1449
1450 /* Only remove list contents. Keep ls_upd. */
1451 list_delete_all_node (ls_upd);
1452
1453 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1454 }
1455
1456 /* Append LSA to update list. */
1457 listnode_add (ls_upd, find);
1458 length += ntohs (find->data->length);
1459
1460 size -= OSPF_LSA_KEY_SIZE;
1461 }
1462
1463 /* Send rest of Link State Update. */
1464 if (listcount (ls_upd) > 0)
1465 {
1466 if (oi->type == OSPF_IFTYPE_NBMA)
1467 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1468 else
1469 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1470
1471 list_delete (ls_upd);
1472 }
1473 else
1474 list_free (ls_upd);
1475}
1476
1477/* Get the list of LSAs from Link State Update packet.
1478 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001479static struct list *
paul718e3742002-12-13 20:15:29 +00001480ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1481 struct ospf_interface *oi, size_t size)
1482{
1483 u_int16_t count, sum;
1484 u_int32_t length;
1485 struct lsa_header *lsah;
1486 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001487 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001488
1489 lsas = list_new ();
1490
1491 count = stream_getl (s);
1492 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1493
1494 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1495 size -= length, stream_forward (s, length), count--)
1496 {
1497 lsah = (struct lsa_header *) STREAM_PNT (s);
1498 length = ntohs (lsah->length);
1499
1500 if (length > size)
1501 {
1502 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1503 break;
1504 }
1505
1506 /* Validate the LSA's LS checksum. */
1507 sum = lsah->checksum;
1508 if (sum != ospf_lsa_checksum (lsah))
1509 {
1510 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1511 sum, lsah->checksum);
1512 continue;
1513 }
1514
1515 /* Examine the LSA's LS type. */
1516 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1517 {
1518 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1519 continue;
1520 }
1521
1522 /*
1523 * What if the received LSA's age is greater than MaxAge?
1524 * Treat it as a MaxAge case -- endo.
1525 */
1526 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1527 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1528
1529#ifdef HAVE_OPAQUE_LSA
1530 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1531 {
1532#ifdef STRICT_OBIT_USAGE_CHECK
1533 if ((IS_OPAQUE_LSA(lsah->type) &&
1534 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1535 || (! IS_OPAQUE_LSA(lsah->type) &&
1536 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1537 {
1538 /*
1539 * This neighbor must know the exact usage of O-bit;
1540 * the bit will be set in Type-9,10,11 LSAs only.
1541 */
1542 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1543 continue;
1544 }
1545#endif /* STRICT_OBIT_USAGE_CHECK */
1546
1547 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1548 if (lsah->type == OSPF_OPAQUE_AS_LSA
1549 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1550 {
1551 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001552 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 +00001553 continue;
1554 }
1555 }
1556 else if (IS_OPAQUE_LSA(lsah->type))
1557 {
1558 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1559 continue;
1560 }
1561#endif /* HAVE_OPAQUE_LSA */
1562
1563 /* Create OSPF LSA instance. */
1564 lsa = ospf_lsa_new ();
1565
1566 /* We may wish to put some error checking if type NSSA comes in
1567 and area not in NSSA mode */
1568 switch (lsah->type)
1569 {
1570 case OSPF_AS_EXTERNAL_LSA:
1571#ifdef HAVE_OPAQUE_LSA
1572 case OSPF_OPAQUE_AS_LSA:
1573 lsa->area = NULL;
1574 break;
1575 case OSPF_OPAQUE_LINK_LSA:
1576 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1577 /* Fallthrough */
1578#endif /* HAVE_OPAQUE_LSA */
1579 default:
1580 lsa->area = oi->area;
1581 break;
1582 }
1583
1584 lsa->data = ospf_lsa_data_new (length);
1585 memcpy (lsa->data, lsah, length);
1586
1587 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001588 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001589 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1590 listnode_add (lsas, lsa);
1591 }
1592
1593 return lsas;
1594}
1595
1596/* Cleanup Update list. */
1597void
hasso52dc7ee2004-09-23 19:18:23 +00001598ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001599{
hasso52dc7ee2004-09-23 19:18:23 +00001600 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001601 struct ospf_lsa *lsa;
1602
1603 for (node = listhead (lsas); node; nextnode (node))
1604 if ((lsa = getdata (node)) != NULL)
1605 ospf_lsa_discard (lsa);
1606
1607 list_delete (lsas);
1608}
1609
1610/* OSPF Link State Update message read -- RFC2328 Section 13. */
1611void
1612ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1613 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1614{
1615 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001616 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001617#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001618 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001619#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001620 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001621 struct ospf_lsa *lsa = NULL;
1622 /* unsigned long ls_req_found = 0; */
1623
1624 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1625
1626 /* Increment statistics. */
1627 oi->ls_upd_in++;
1628
1629 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001630 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001631 if (nbr == NULL)
1632 {
1633 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1634 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1635 return;
1636 }
1637
1638 /* Check neighbor state. */
1639 if (nbr->state < NSM_Exchange)
1640 {
ajs3aa8d5f2004-12-11 18:00:06 +00001641 zlog_warn ("Link State Update: "
1642 "Neighbor[%s] state %s is less than Exchange",
1643 inet_ntoa (ospfh->router_id),
1644 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001645 return;
1646 }
1647
1648 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1649 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1650 * of section 13.
1651 */
1652 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1653
1654#ifdef HAVE_OPAQUE_LSA
1655 /*
1656 * Prepare two kinds of lists to clean up unwanted self-originated
1657 * Opaque-LSAs from the routing domain as soon as possible.
1658 */
1659 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1660 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1661
1662 /*
1663 * If self-originated Opaque-LSAs that have flooded before restart
1664 * are contained in the received LSUpd message, corresponding LSReq
1665 * messages to be sent may have to be modified.
1666 * To eliminate possible race conditions such that flushing and normal
1667 * updating for the same LSA would take place alternately, this trick
1668 * must be done before entering to the loop below.
1669 */
1670 ospf_opaque_adjust_lsreq (nbr, lsas);
1671#endif /* HAVE_OPAQUE_LSA */
1672
1673#define DISCARD_LSA(L,N) {\
1674 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001675 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 +00001676 ospf_lsa_discard (L); \
1677 continue; }
1678
1679 /* Process each LSA received in the one packet. */
1680 for (node = listhead (lsas); node; node = next)
1681 {
1682 struct ospf_lsa *ls_ret, *current;
1683 int ret = 1;
1684
1685 next = node->next;
1686
1687 lsa = getdata (node);
1688
paul718e3742002-12-13 20:15:29 +00001689 if (IS_DEBUG_OSPF_NSSA)
1690 {
1691 char buf1[INET_ADDRSTRLEN];
1692 char buf2[INET_ADDRSTRLEN];
1693 char buf3[INET_ADDRSTRLEN];
1694
ajs2a42e282004-12-08 18:43:03 +00001695 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001696 lsa->data->type,
1697 inet_ntop (AF_INET, &ospfh->router_id,
1698 buf1, INET_ADDRSTRLEN),
1699 inet_ntop (AF_INET, &lsa->data->id,
1700 buf2, INET_ADDRSTRLEN),
1701 inet_ntop (AF_INET, &lsa->data->adv_router,
1702 buf3, INET_ADDRSTRLEN));
1703 }
paul718e3742002-12-13 20:15:29 +00001704
1705 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1706
1707 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1708
1709 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1710
1711 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1712
1713 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1714
1715 /* Do take in Type-7's if we are an NSSA */
1716
1717 /* If we are also an ABR, later translate them to a Type-5 packet */
1718
1719 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1720 translate them to a separate Type-5 packet. */
1721
1722 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1723 /* Reject from STUB or NSSA */
1724 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1725 {
1726 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001727 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001728 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001729 }
1730
paul718e3742002-12-13 20:15:29 +00001731 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1732 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1733 {
1734 DISCARD_LSA (lsa,2);
1735 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001736 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001737 }
paul718e3742002-12-13 20:15:29 +00001738
1739 /* Find the LSA in the current database. */
1740
1741 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1742
1743 /* If the LSA's LS age is equal to MaxAge, and there is currently
1744 no instance of the LSA in the router's link state database,
1745 and none of router's neighbors are in states Exchange or Loading,
1746 then take the following actions. */
1747
1748 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001749 (ospf_nbr_count (oi, NSM_Exchange) +
1750 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001751 {
1752 /* Response Link State Acknowledgment. */
1753 ospf_ls_ack_send (nbr, lsa);
1754
1755 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001756 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1757 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001758 DISCARD_LSA (lsa, 3);
1759 }
1760
1761#ifdef HAVE_OPAQUE_LSA
1762 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001763 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001764 {
1765 /*
1766 * Even if initial flushing seems to be completed, there might
1767 * be a case that self-originated LSA with MaxAge still remain
1768 * in the routing domain.
1769 * Just send an LSAck message to cease retransmission.
1770 */
1771 if (IS_LSA_MAXAGE (lsa))
1772 {
1773 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1774 ospf_ls_ack_send (nbr, lsa);
1775 ospf_lsa_discard (lsa);
1776
1777 if (current != NULL && ! IS_LSA_MAXAGE (current))
1778 ospf_opaque_lsa_refresh_schedule (current);
1779 continue;
1780 }
1781
1782 /*
1783 * If an instance of self-originated Opaque-LSA is not found
1784 * in the LSDB, there are some possible cases here.
1785 *
1786 * 1) This node lost opaque-capability after restart.
1787 * 2) Else, a part of opaque-type is no more supported.
1788 * 3) Else, a part of opaque-id is no more supported.
1789 *
1790 * Anyway, it is still this node's responsibility to flush it.
1791 * Otherwise, the LSA instance remains in the routing domain
1792 * until its age reaches to MaxAge.
1793 */
1794 if (current == NULL)
1795 {
1796 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001797 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001798
1799 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1800 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1801 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1802 continue;
1803 }
1804 }
1805#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001806 /* It might be happen that received LSA is self-originated network LSA, but
1807 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1808 * Link State ID is one of the router's own IP interface addresses but whose
1809 * Advertising Router is not equal to the router's own Router ID
1810 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1811 */
1812
1813 if(lsa->data->type == OSPF_NETWORK_LSA)
1814 {
hasso52dc7ee2004-09-23 19:18:23 +00001815 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001816 int Flag = 0;
1817
1818 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1819 {
1820 struct ospf_interface *out_if = getdata(oi_node);
1821 if(out_if == NULL)
1822 break;
1823
1824 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1825 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1826 {
1827 if(out_if->network_lsa_self)
1828 {
1829 ospf_lsa_flush_area(lsa,out_if->area);
1830 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001831 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001832 lsa, (int) lsa->data->type);
1833 ospf_lsa_discard (lsa);
1834 Flag = 1;
1835 }
1836 break;
1837 }
1838 }
1839 if(Flag)
1840 continue;
1841 }
paul718e3742002-12-13 20:15:29 +00001842
1843 /* (5) Find the instance of this LSA that is currently contained
1844 in the router's link state database. If there is no
1845 database copy, or the received LSA is more recent than
1846 the database copy the following steps must be performed. */
1847
1848 if (current == NULL ||
1849 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1850 {
1851 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001852 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001853 DISCARD_LSA (lsa, 4);
1854 continue;
1855 }
1856
1857 /* (6) Else, If there is an instance of the LSA on the sending
1858 neighbor's Link state request list, an error has occurred in
1859 the Database Exchange process. In this case, restart the
1860 Database Exchange process by generating the neighbor event
1861 BadLSReq for the sending neighbor and stop processing the
1862 Link State Update packet. */
1863
1864 if (ospf_ls_request_lookup (nbr, lsa))
1865 {
1866 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001867 zlog_warn("LSA[%s] instance exists on Link state request list",
1868 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001869
1870 /* Clean list of LSAs. */
1871 ospf_upd_list_clean (lsas);
1872 /* this lsa is not on lsas list already. */
1873 ospf_lsa_discard (lsa);
1874#ifdef HAVE_OPAQUE_LSA
1875 list_delete (mylsa_acks);
1876 list_delete (mylsa_upds);
1877#endif /* HAVE_OPAQUE_LSA */
1878 return;
1879 }
1880
1881 /* If the received LSA is the same instance as the database copy
1882 (i.e., neither one is more recent) the following two steps
1883 should be performed: */
1884
1885 if (ret == 0)
1886 {
1887 /* If the LSA is listed in the Link state retransmission list
1888 for the receiving adjacency, the router itself is expecting
1889 an acknowledgment for this LSA. The router should treat the
1890 received LSA as an acknowledgment by removing the LSA from
1891 the Link state retransmission list. This is termed an
1892 "implied acknowledgment". */
1893
1894 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1895
1896 if (ls_ret != NULL)
1897 {
1898 ospf_ls_retransmit_delete (nbr, ls_ret);
1899
1900 /* Delayed acknowledgment sent if advertisement received
1901 from Designated Router, otherwise do nothing. */
1902 if (oi->state == ISM_Backup)
1903 if (NBR_IS_DR (nbr))
1904 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1905
1906 DISCARD_LSA (lsa, 5);
1907 }
1908 else
1909 /* Acknowledge the receipt of the LSA by sending a
1910 Link State Acknowledgment packet back out the receiving
1911 interface. */
1912 {
1913 ospf_ls_ack_send (nbr, lsa);
1914 DISCARD_LSA (lsa, 6);
1915 }
1916 }
1917
1918 /* The database copy is more recent. If the database copy
1919 has LS age equal to MaxAge and LS sequence number equal to
1920 MaxSequenceNumber, simply discard the received LSA without
1921 acknowledging it. (In this case, the LSA's LS sequence number is
1922 wrapping, and the MaxSequenceNumber LSA must be completely
1923 flushed before any new LSA instance can be introduced). */
1924
1925 else if (ret > 0) /* Database copy is more recent */
1926 {
1927 if (IS_LSA_MAXAGE (current) &&
1928 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1929 {
1930 DISCARD_LSA (lsa, 7);
1931 }
1932 /* Otherwise, as long as the database copy has not been sent in a
1933 Link State Update within the last MinLSArrival seconds, send the
1934 database copy back to the sending neighbor, encapsulated within
1935 a Link State Update Packet. The Link State Update Packet should
1936 be sent directly to the neighbor. In so doing, do not put the
1937 database copy of the LSA on the neighbor's link state
1938 retransmission list, and do not acknowledge the received (less
1939 recent) LSA instance. */
1940 else
1941 {
1942 struct timeval now;
1943
1944 gettimeofday (&now, NULL);
1945
1946 if (tv_cmp (tv_sub (now, current->tv_orig),
1947 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1948 /* Trap NSSA type later.*/
1949 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1950 DISCARD_LSA (lsa, 8);
1951 }
1952 }
1953 }
1954
1955#ifdef HAVE_OPAQUE_LSA
1956 /*
1957 * Now that previously originated Opaque-LSAs those which not yet
1958 * installed into LSDB are captured, take several steps to clear
1959 * them completely from the routing domain, before proceeding to
1960 * origination for the current target Opaque-LSAs.
1961 */
1962 while (listcount (mylsa_acks) > 0)
1963 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1964
1965 if (listcount (mylsa_upds) > 0)
1966 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1967
1968 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001969 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001970#endif /* HAVE_OPAQUE_LSA */
1971
1972 assert (listcount (lsas) == 0);
1973 list_delete (lsas);
1974}
1975
1976/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1977void
1978ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1979 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1980{
1981 struct ospf_neighbor *nbr;
1982#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001983 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001984#endif /* HAVE_OPAQUE_LSA */
1985
1986 /* increment statistics. */
1987 oi->ls_ack_in++;
1988
pauld3f0d622004-05-05 15:27:15 +00001989 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001990 if (nbr == NULL)
1991 {
1992 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1993 inet_ntoa (ospfh->router_id));
1994 return;
1995 }
1996
1997 if (nbr->state < NSM_Exchange)
1998 {
ajs3aa8d5f2004-12-11 18:00:06 +00001999 zlog_warn ("Link State Acknowledgment: "
2000 "Neighbor[%s] state %s is less than Exchange",
2001 inet_ntoa (ospfh->router_id),
2002 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002003 return;
2004 }
2005
2006#ifdef HAVE_OPAQUE_LSA
2007 opaque_acks = list_new ();
2008#endif /* HAVE_OPAQUE_LSA */
2009
2010 while (size >= OSPF_LSA_HEADER_SIZE)
2011 {
2012 struct ospf_lsa *lsa, *lsr;
2013
2014 lsa = ospf_lsa_new ();
2015 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2016
2017 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2018 size -= OSPF_LSA_HEADER_SIZE;
2019 stream_forward (s, OSPF_LSA_HEADER_SIZE);
2020
2021 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2022 {
2023 lsa->data = NULL;
2024 ospf_lsa_discard (lsa);
2025 continue;
2026 }
2027
2028 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2029
2030 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2031 {
2032#ifdef HAVE_OPAQUE_LSA
2033 /* Keep this LSA entry for later reference. */
2034 if (IS_OPAQUE_LSA (lsr->data->type))
2035 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2036#endif /* HAVE_OPAQUE_LSA */
2037
2038 ospf_ls_retransmit_delete (nbr, lsr);
2039 }
2040
2041 lsa->data = NULL;
2042 ospf_lsa_discard (lsa);
2043 }
2044
2045#ifdef HAVE_OPAQUE_LSA
2046 if (listcount (opaque_acks) > 0)
2047 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2048
2049 list_delete (opaque_acks);
2050 return;
2051#endif /* HAVE_OPAQUE_LSA */
2052}
2053
2054struct stream *
2055ospf_recv_packet (int fd, struct interface **ifp)
2056{
2057 int ret;
2058 struct ip iph;
2059 u_int16_t ip_len;
2060 struct stream *ibuf;
2061 unsigned int ifindex = 0;
2062 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002063 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002064 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002065 struct msghdr msgh;
2066
paul68defd62004-09-27 07:27:13 +00002067 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002068 msgh.msg_iov = &iov;
2069 msgh.msg_iovlen = 1;
2070 msgh.msg_control = (caddr_t) buff;
2071 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002072
paul718e3742002-12-13 20:15:29 +00002073 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2074
2075 if (ret != sizeof (iph))
2076 {
2077 zlog_warn ("ospf_recv_packet packet smaller than ip header");
gdtbe210242004-12-29 20:12:59 +00002078 /* XXX: We peeked, and thus perhaps should discard this packet. */
paul718e3742002-12-13 20:15:29 +00002079 return NULL;
2080 }
paul18b12c32004-10-05 14:38:29 +00002081
2082 sockopt_iphdrincl_swab_systoh (&iph);
2083
paul6b333612004-10-11 10:11:25 +00002084 ip_len = iph.ip_len;
2085
paul239aecc2003-12-08 10:34:54 +00002086#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002087 /*
2088 * Kernel network code touches incoming IP header parameters,
2089 * before protocol specific processing.
2090 *
2091 * 1) Convert byteorder to host representation.
2092 * --> ip_len, ip_id, ip_off
2093 *
2094 * 2) Adjust ip_len to strip IP header size!
2095 * --> If user process receives entire IP packet via RAW
2096 * socket, it must consider adding IP header size to
2097 * the "ip_len" field of "ip" structure.
2098 *
2099 * For more details, see <netinet/ip_input.c>.
2100 */
2101 ip_len = ip_len + (iph.ip_hl << 2);
2102#endif
2103
2104 ibuf = stream_new (ip_len);
2105 iov.iov_base = STREAM_DATA (ibuf);
2106 iov.iov_len = ip_len;
2107 ret = recvmsg (fd, &msgh, 0);
2108
paul863082d2004-08-19 04:43:43 +00002109 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002110
2111 *ifp = if_lookup_by_index (ifindex);
2112
2113 if (ret != ip_len)
2114 {
2115 zlog_warn ("ospf_recv_packet short read. "
2116 "ip_len %d bytes read %d", ip_len, ret);
2117 stream_free (ibuf);
2118 return NULL;
2119 }
2120
2121 return ibuf;
2122}
2123
2124struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002125ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002126 struct ip *iph, struct ospf_header *ospfh)
2127{
2128 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002129 struct ospf_vl_data *vl_data;
2130 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002131 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002132
2133 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2134 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002135 return NULL;
paul718e3742002-12-13 20:15:29 +00002136
pauld3f0d622004-05-05 15:27:15 +00002137 /* look for local OSPF interface matching the destination
2138 * to determine Area ID. We presume therefore the destination address
2139 * is unique, or at least (for "unnumbered" links), not used in other
2140 * areas
2141 */
2142 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2143 iph->ip_dst)) == NULL)
2144 return NULL;
paul718e3742002-12-13 20:15:29 +00002145
paul020709f2003-04-04 02:44:16 +00002146 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002147 {
2148 if ((vl_data = getdata (node)) == NULL)
2149 continue;
2150
paul020709f2003-04-04 02:44:16 +00002151 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002152 if (!vl_area)
2153 continue;
2154
2155 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2156 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2157 {
2158 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002159 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002160 IF_NAME (vl_data->vl_oi));
2161 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2162 {
2163 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002164 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002165 return NULL;
2166 }
2167
2168 return vl_data->vl_oi;
2169 }
2170 }
2171
2172 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002173 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002174
pauld3f0d622004-05-05 15:27:15 +00002175 return NULL;
paul718e3742002-12-13 20:15:29 +00002176}
2177
2178int
2179ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2180{
2181 /* Check match the Area ID of the receiving interface. */
2182 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2183 return 1;
2184
2185 return 0;
2186}
2187
2188/* Unbound socket will accept any Raw IP packets if proto is matched.
2189 To prevent it, compare src IP address and i/f address with masking
2190 i/f network mask. */
2191int
2192ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2193{
2194 struct in_addr mask, me, him;
2195
2196 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2197 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2198 return 1;
2199
2200 masklen2ip (oi->address->prefixlen, &mask);
2201
2202 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2203 him.s_addr = ip_src.s_addr & mask.s_addr;
2204
2205 if (IPV4_ADDR_SAME (&me, &him))
2206 return 1;
2207
2208 return 0;
2209}
2210
2211int
2212ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2213 struct ospf_header *ospfh)
2214{
2215 int ret = 0;
2216 struct crypt_key *ck;
2217
2218 switch (ntohs (ospfh->auth_type))
2219 {
2220 case OSPF_AUTH_NULL:
2221 ret = 1;
2222 break;
2223 case OSPF_AUTH_SIMPLE:
2224 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2225 ret = 1;
2226 else
2227 ret = 0;
2228 break;
2229 case OSPF_AUTH_CRYPTOGRAPHIC:
2230 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2231 {
2232 ret = 0;
2233 break;
2234 }
2235
2236 /* This is very basic, the digest processing is elsewhere */
2237 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2238 ospfh->u.crypt.key_id == ck->key_id &&
2239 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2240 ret = 1;
2241 else
2242 ret = 0;
2243 break;
2244 default:
2245 ret = 0;
2246 break;
2247 }
2248
2249 return ret;
2250}
2251
2252int
2253ospf_check_sum (struct ospf_header *ospfh)
2254{
2255 u_int32_t ret;
2256 u_int16_t sum;
2257 int in_cksum (void *ptr, int nbytes);
2258
2259 /* clear auth_data for checksum. */
2260 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2261
2262 /* keep checksum and clear. */
2263 sum = ospfh->checksum;
2264 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2265
2266 /* calculate checksum. */
2267 ret = in_cksum (ospfh, ntohs (ospfh->length));
2268
2269 if (ret != sum)
2270 {
2271 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2272 ret, sum);
2273 return 0;
2274 }
2275
2276 return 1;
2277}
2278
2279/* OSPF Header verification. */
2280int
2281ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2282 struct ip *iph, struct ospf_header *ospfh)
2283{
2284 /* check version. */
2285 if (ospfh->version != OSPF_VERSION)
2286 {
2287 zlog_warn ("interface %s: ospf_read version number mismatch.",
2288 IF_NAME (oi));
2289 return -1;
2290 }
2291
2292 /* Check Area ID. */
2293 if (!ospf_check_area_id (oi, ospfh))
2294 {
2295 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2296 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2297 return -1;
2298 }
2299
2300 /* Check network mask, Silently discarded. */
2301 if (! ospf_check_network_mask (oi, iph->ip_src))
2302 {
2303 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2304 IF_NAME (oi), inet_ntoa (iph->ip_src));
2305 return -1;
2306 }
2307
2308 /* Check authentication. */
2309 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2310 {
2311 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2312 IF_NAME (oi));
2313 return -1;
2314 }
2315
2316 if (! ospf_check_auth (oi, ibuf, ospfh))
2317 {
2318 zlog_warn ("interface %s: ospf_read authentication failed.",
2319 IF_NAME (oi));
2320 return -1;
2321 }
2322
2323 /* if check sum is invalid, packet is discarded. */
2324 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2325 {
2326 if (! ospf_check_sum (ospfh))
2327 {
2328 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2329 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2330 return -1;
2331 }
2332 }
2333 else
2334 {
2335 if (ospfh->checksum != 0)
2336 return -1;
2337 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2338 {
2339 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2340 IF_NAME (oi));
2341 return -1;
2342 }
2343 }
2344
2345 return 0;
2346}
2347
2348/* Starting point of packet process function. */
2349int
2350ospf_read (struct thread *thread)
2351{
2352 int ret;
2353 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002354 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002355 struct ospf_interface *oi;
2356 struct ip *iph;
2357 struct ospf_header *ospfh;
2358 u_int16_t length;
2359 struct interface *ifp;
2360
2361 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002362 ospf = THREAD_ARG (thread);
2363 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002364
2365 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002366 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002367 if (ibuf == NULL)
2368 return -1;
2369
paul06f953f2004-10-22 17:00:38 +00002370 iph = (struct ip *) STREAM_DATA (ibuf);
2371 sockopt_iphdrincl_swab_systoh (iph);
2372
paulac191232004-10-22 12:05:17 +00002373 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002374 /* Handle cases where the platform does not support retrieving the ifindex,
2375 and also platforms (such as Solaris 8) that claim to support ifindex
2376 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002377 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002378
pauld3f0d622004-05-05 15:27:15 +00002379 if (ifp == NULL)
2380 {
2381 stream_free (ibuf);
2382 return 0;
2383 }
paul6b333612004-10-11 10:11:25 +00002384
paul718e3742002-12-13 20:15:29 +00002385 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002386 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002387
2388 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002389 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002390 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002391
paul718e3742002-12-13 20:15:29 +00002392 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002393 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002394 {
pauld3241812003-09-29 12:42:39 +00002395 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2396 {
ajs2a42e282004-12-08 18:43:03 +00002397 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002398 inet_ntoa (iph->ip_src));
2399 }
paul718e3742002-12-13 20:15:29 +00002400 stream_free (ibuf);
2401 return 0;
2402 }
2403
2404 /* Adjust size to message length. */
2405 stream_forward (ibuf, iph->ip_hl * 4);
2406
2407 /* Get ospf packet header. */
2408 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2409
2410 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002411 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002412
2413 /* if no local ospf_interface,
2414 * or header area is backbone but ospf_interface is not
2415 * check for VLINK interface
2416 */
2417 if ( (oi == NULL) ||
2418 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2419 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2420 )
2421 {
2422 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2423 {
2424 zlog_warn ("Packet from [%s] received on link %s"
2425 " but no ospf_interface",
2426 inet_ntoa (iph->ip_src), ifp->name);
2427 stream_free (ibuf);
2428 return 0;
2429 }
2430 }
2431
2432 /* else it must be a local ospf interface, check it was received on
2433 * correct link
2434 */
2435 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002436 {
2437 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002438 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002439 stream_free (ibuf);
2440 return 0;
2441 }
ajs847947f2005-02-02 18:38:48 +00002442 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002443 {
ajsba6454e2005-02-08 15:37:30 +00002444 char buf[2][INET_ADDRSTRLEN];
2445 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002446 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002447 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2448 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2449 ifp->name, if_flag_dump(ifp->flags));
ajsc3eab872005-01-29 15:52:07 +00002450 stream_free (ibuf);
ajsba6454e2005-02-08 15:37:30 +00002451 /* Fix multicast memberships? */
2452 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2453 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2454 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2455 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2456 if (oi->multicast_memberships)
2457 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002458 return 0;
2459 }
paul718e3742002-12-13 20:15:29 +00002460
2461 /*
2462 * If the received packet is destined for AllDRouters, the packet
2463 * should be accepted only if the received ospf interface state is
2464 * either DR or Backup -- endo.
2465 */
2466 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2467 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2468 {
ajsba6454e2005-02-08 15:37:30 +00002469 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002470 inet_ntoa (iph->ip_src), IF_NAME (oi),
2471 LOOKUP (ospf_ism_state_msg, oi->state));
2472 stream_free (ibuf);
ajsba6454e2005-02-08 15:37:30 +00002473 /* Try to fix multicast membership. */
2474 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2475 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002476 return 0;
2477 }
2478
2479 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002480 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2481 {
paul718e3742002-12-13 20:15:29 +00002482 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002483 {
ajs2a42e282004-12-08 18:43:03 +00002484 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002485 ospf_packet_dump (ibuf);
2486 }
paul718e3742002-12-13 20:15:29 +00002487
ajs2a42e282004-12-08 18:43:03 +00002488 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002489 ospf_packet_type_str[ospfh->type],
2490 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002491 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2492 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002493
2494 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002495 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002496 }
paul718e3742002-12-13 20:15:29 +00002497
2498 /* Some header verification. */
2499 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2500 if (ret < 0)
2501 {
pauld3241812003-09-29 12:42:39 +00002502 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2503 {
ajs2a42e282004-12-08 18:43:03 +00002504 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002505 "dropping.",
2506 ospf_packet_type_str[ospfh->type],
2507 inet_ntoa (iph->ip_src));
2508 }
paul718e3742002-12-13 20:15:29 +00002509 stream_free (ibuf);
2510 return ret;
2511 }
2512
2513 stream_forward (ibuf, OSPF_HEADER_SIZE);
2514
2515 /* Adjust size to message length. */
2516 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2517
2518 /* Read rest of the packet and call each sort of packet routine. */
2519 switch (ospfh->type)
2520 {
2521 case OSPF_MSG_HELLO:
2522 ospf_hello (iph, ospfh, ibuf, oi, length);
2523 break;
2524 case OSPF_MSG_DB_DESC:
2525 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2526 break;
2527 case OSPF_MSG_LS_REQ:
2528 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2529 break;
2530 case OSPF_MSG_LS_UPD:
2531 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2532 break;
2533 case OSPF_MSG_LS_ACK:
2534 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2535 break;
2536 default:
2537 zlog (NULL, LOG_WARNING,
2538 "interface %s: OSPF packet header type %d is illegal",
2539 IF_NAME (oi), ospfh->type);
2540 break;
2541 }
2542
2543 stream_free (ibuf);
2544 return 0;
2545}
2546
2547/* Make OSPF header. */
2548void
2549ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2550{
2551 struct ospf_header *ospfh;
2552
2553 ospfh = (struct ospf_header *) STREAM_DATA (s);
2554
2555 ospfh->version = (u_char) OSPF_VERSION;
2556 ospfh->type = (u_char) type;
2557
paul68980082003-03-25 05:07:42 +00002558 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002559
2560 ospfh->checksum = 0;
2561 ospfh->area_id = oi->area->area_id;
2562 ospfh->auth_type = htons (ospf_auth_type (oi));
2563
2564 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2565
2566 ospf_output_forward (s, OSPF_HEADER_SIZE);
2567}
2568
2569/* Make Authentication Data. */
2570int
2571ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2572{
2573 struct crypt_key *ck;
2574
2575 switch (ospf_auth_type (oi))
2576 {
2577 case OSPF_AUTH_NULL:
2578 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2579 break;
2580 case OSPF_AUTH_SIMPLE:
2581 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2582 OSPF_AUTH_SIMPLE_SIZE);
2583 break;
2584 case OSPF_AUTH_CRYPTOGRAPHIC:
2585 /* If key is not set, then set 0. */
2586 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2587 {
2588 ospfh->u.crypt.zero = 0;
2589 ospfh->u.crypt.key_id = 0;
2590 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2591 }
2592 else
2593 {
2594 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2595 ospfh->u.crypt.zero = 0;
2596 ospfh->u.crypt.key_id = ck->key_id;
2597 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2598 }
2599 /* note: the seq is done in ospf_make_md5_digest() */
2600 break;
2601 default:
2602 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2603 break;
2604 }
2605
2606 return 0;
2607}
2608
2609/* Fill rest of OSPF header. */
2610void
2611ospf_fill_header (struct ospf_interface *oi,
2612 struct stream *s, u_int16_t length)
2613{
2614 struct ospf_header *ospfh;
2615
2616 ospfh = (struct ospf_header *) STREAM_DATA (s);
2617
2618 /* Fill length. */
2619 ospfh->length = htons (length);
2620
2621 /* Calculate checksum. */
2622 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2623 ospfh->checksum = in_cksum (ospfh, length);
2624 else
2625 ospfh->checksum = 0;
2626
2627 /* Add Authentication Data. */
2628 ospf_make_auth (oi, ospfh);
2629}
2630
2631int
2632ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2633{
2634 struct ospf_neighbor *nbr;
2635 struct route_node *rn;
2636 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2637 struct in_addr mask;
2638 unsigned long p;
2639 int flag = 0;
2640
2641 /* Set netmask of interface. */
2642 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2643 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2644 masklen2ip (oi->address->prefixlen, &mask);
2645 else
2646 memset ((char *) &mask, 0, sizeof (struct in_addr));
2647 stream_put_ipv4 (s, mask.s_addr);
2648
2649 /* Set Hello Interval. */
2650 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2651
2652 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002653 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002654 OPTIONS(oi), IF_NAME (oi));
2655
2656 /* Set Options. */
2657 stream_putc (s, OPTIONS (oi));
2658
2659 /* Set Router Priority. */
2660 stream_putc (s, PRIORITY (oi));
2661
2662 /* Set Router Dead Interval. */
2663 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2664
2665 /* Set Designated Router. */
2666 stream_put_ipv4 (s, DR (oi).s_addr);
2667
paul3a9eb092005-02-08 11:29:41 +00002668 p = stream_get_putp (s);
paul718e3742002-12-13 20:15:29 +00002669
2670 /* Set Backup Designated Router. */
2671 stream_put_ipv4 (s, BDR (oi).s_addr);
2672
2673 /* Add neighbor seen. */
2674 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002675 if ((nbr = rn->info))
2676 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2677 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2678 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2679 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002680 {
2681 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002682 if (nbr->d_router.s_addr != 0
2683 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2684 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2685 flag = 1;
paul718e3742002-12-13 20:15:29 +00002686
2687 stream_put_ipv4 (s, nbr->router_id.s_addr);
2688 length += 4;
2689 }
2690
2691 /* Let neighbor generate BackupSeen. */
2692 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002693 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002694
2695 return length;
2696}
2697
2698int
2699ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2700 struct stream *s)
2701{
2702 struct ospf_lsa *lsa;
2703 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2704 u_char options;
2705 unsigned long pp;
2706 int i;
2707 struct ospf_lsdb *lsdb;
2708
2709 /* Set Interface MTU. */
2710 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2711 stream_putw (s, 0);
2712 else
2713 stream_putw (s, oi->ifp->mtu);
2714
2715 /* Set Options. */
2716 options = OPTIONS (oi);
2717#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002718 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002719 {
2720 if (IS_SET_DD_I (nbr->dd_flags)
2721 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2722 /*
2723 * Set O-bit in the outgoing DD packet for capablity negotiation,
2724 * if one of following case is applicable.
2725 *
2726 * 1) WaitTimer expiration event triggered the neighbor state to
2727 * change to Exstart, but no (valid) DD packet has received
2728 * from the neighbor yet.
2729 *
2730 * 2) At least one DD packet with O-bit on has received from the
2731 * neighbor.
2732 */
2733 SET_FLAG (options, OSPF_OPTION_O);
2734 }
2735#endif /* HAVE_OPAQUE_LSA */
2736 stream_putc (s, options);
2737
2738 /* Keep pointer to flags. */
2739 pp = stream_get_putp (s);
2740 stream_putc (s, nbr->dd_flags);
2741
2742 /* Set DD Sequence Number. */
2743 stream_putl (s, nbr->dd_seqnum);
2744
2745 if (ospf_db_summary_isempty (nbr))
2746 {
2747 if (nbr->state >= NSM_Exchange)
2748 {
2749 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2750 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002751 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002752 }
2753 return length;
2754 }
2755
2756 /* Describe LSA Header from Database Summary List. */
2757 lsdb = &nbr->db_sum;
2758
2759 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2760 {
2761 struct route_table *table = lsdb->type[i].db;
2762 struct route_node *rn;
2763
2764 for (rn = route_top (table); rn; rn = route_next (rn))
2765 if ((lsa = rn->info) != NULL)
2766 {
2767#ifdef HAVE_OPAQUE_LSA
2768 if (IS_OPAQUE_LSA (lsa->data->type)
2769 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2770 {
2771 /* Suppress advertising opaque-informations. */
2772 /* Remove LSA from DB summary list. */
2773 ospf_lsdb_delete (lsdb, lsa);
2774 continue;
2775 }
2776#endif /* HAVE_OPAQUE_LSA */
2777
2778 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2779 {
2780 struct lsa_header *lsah;
2781 u_int16_t ls_age;
2782
2783 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002784 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002785 break;
2786
2787 /* Keep pointer to LS age. */
2788 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2789 stream_get_putp (s));
2790
2791 /* Proceed stream pointer. */
2792 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2793 length += OSPF_LSA_HEADER_SIZE;
2794
2795 /* Set LS age. */
2796 ls_age = LS_AGE (lsa);
2797 lsah->ls_age = htons (ls_age);
2798
2799 }
2800
2801 /* Remove LSA from DB summary list. */
2802 ospf_lsdb_delete (lsdb, lsa);
2803 }
2804 }
2805
2806 return length;
2807}
2808
2809int
2810ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2811 unsigned long delta, struct ospf_neighbor *nbr,
2812 struct ospf_lsa *lsa)
2813{
2814 struct ospf_interface *oi;
2815
2816 oi = nbr->oi;
2817
2818 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002819 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002820 return 0;
2821
2822 stream_putl (s, lsa->data->type);
2823 stream_put_ipv4 (s, lsa->data->id.s_addr);
2824 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2825
2826 ospf_lsa_unlock (nbr->ls_req_last);
2827 nbr->ls_req_last = ospf_lsa_lock (lsa);
2828
2829 *length += 12;
2830 return 1;
2831}
2832
2833int
2834ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2835{
2836 struct ospf_lsa *lsa;
2837 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2838 unsigned long delta = stream_get_putp(s)+12;
2839 struct route_table *table;
2840 struct route_node *rn;
2841 int i;
2842 struct ospf_lsdb *lsdb;
2843
2844 lsdb = &nbr->ls_req;
2845
2846 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2847 {
2848 table = lsdb->type[i].db;
2849 for (rn = route_top (table); rn; rn = route_next (rn))
2850 if ((lsa = (rn->info)) != NULL)
2851 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2852 {
2853 route_unlock_node (rn);
2854 break;
2855 }
2856 }
2857 return length;
2858}
2859
2860int
2861ls_age_increment (struct ospf_lsa *lsa, int delay)
2862{
2863 int age;
2864
2865 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2866
2867 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2868}
2869
2870int
hasso52dc7ee2004-09-23 19:18:23 +00002871ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002872{
2873 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002874 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002875 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002876 unsigned int size_noauth;
paul718e3742002-12-13 20:15:29 +00002877 unsigned long delta = stream_get_putp (s);
2878 unsigned long pp;
2879 int count = 0;
2880
2881 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002882 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002883
paul718e3742002-12-13 20:15:29 +00002884 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002885 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002886
gdt86f1fd92005-01-10 14:20:43 +00002887 /* Calculate amount of packet usable for data. */
2888 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2889
paul718e3742002-12-13 20:15:29 +00002890 while ((node = listhead (update)) != NULL)
2891 {
2892 struct lsa_header *lsah;
2893 u_int16_t ls_age;
2894
2895 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002896 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002897
2898 lsa = getdata (node);
2899 assert (lsa);
2900 assert (lsa->data);
2901
paul68b73392004-09-12 14:21:37 +00002902 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002903 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002904 break;
2905
paul718e3742002-12-13 20:15:29 +00002906 /* Keep pointer to LS age. */
2907 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2908
2909 /* Put LSA to Link State Request. */
2910 stream_put (s, lsa->data, ntohs (lsa->data->length));
2911
2912 /* Set LS age. */
2913 /* each hop must increment an lsa_age by transmit_delay
2914 of OSPF interface */
2915 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2916 lsah->ls_age = htons (ls_age);
2917
2918 length += ntohs (lsa->data->length);
2919 count++;
2920
2921 list_delete_node (update, node);
2922 ospf_lsa_unlock (lsa);
2923 }
2924
2925 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002926 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002927
2928 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002929 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002930 return length;
2931}
2932
2933int
hasso52dc7ee2004-09-23 19:18:23 +00002934ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002935{
hasso52dc7ee2004-09-23 19:18:23 +00002936 struct list *rm_list;
2937 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002938 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2939 unsigned long delta = stream_get_putp(s) + 24;
2940 struct ospf_lsa *lsa;
2941
2942 rm_list = list_new ();
2943
2944 for (node = listhead (ack); node; nextnode (node))
2945 {
2946 lsa = getdata (node);
2947 assert (lsa);
2948
gdt86f1fd92005-01-10 14:20:43 +00002949 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002950 break;
2951
2952 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2953 length += OSPF_LSA_HEADER_SIZE;
2954
2955 listnode_add (rm_list, lsa);
2956 }
2957
2958 /* Remove LSA from LS-Ack list. */
2959 for (node = listhead (rm_list); node; nextnode (node))
2960 {
2961 lsa = (struct ospf_lsa *) getdata (node);
2962
2963 listnode_delete (ack, lsa);
2964 ospf_lsa_unlock (lsa);
2965 }
2966
2967 list_delete (rm_list);
2968
2969 return length;
2970}
2971
2972void
2973ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2974{
2975 struct ospf_packet *op;
2976 u_int16_t length = OSPF_HEADER_SIZE;
2977
2978 op = ospf_packet_new (oi->ifp->mtu);
2979
2980 /* Prepare OSPF common header. */
2981 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2982
2983 /* Prepare OSPF Hello body. */
2984 length += ospf_make_hello (oi, op->s);
2985
2986 /* Fill OSPF header. */
2987 ospf_fill_header (oi, op->s, length);
2988
2989 /* Set packet length. */
2990 op->length = length;
2991
2992 op->dst.s_addr = addr->s_addr;
2993
2994 /* Add packet to the interface output queue. */
2995 ospf_packet_add (oi, op);
2996
2997 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002998 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002999}
3000
3001void
3002ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3003{
3004 struct ospf_interface *oi;
3005
3006 oi = nbr_nbma->oi;
3007 assert(oi);
3008
3009 /* If this is passive interface, do not send OSPF Hello. */
3010 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3011 return;
3012
3013 if (oi->type != OSPF_IFTYPE_NBMA)
3014 return;
3015
3016 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3017 return;
3018
3019 if (PRIORITY(oi) == 0)
3020 return;
3021
3022 if (nbr_nbma->priority == 0
3023 && oi->state != ISM_DR && oi->state != ISM_Backup)
3024 return;
3025
3026 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3027}
3028
3029int
3030ospf_poll_timer (struct thread *thread)
3031{
3032 struct ospf_nbr_nbma *nbr_nbma;
3033
3034 nbr_nbma = THREAD_ARG (thread);
3035 nbr_nbma->t_poll = NULL;
3036
3037 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003038 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003039 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3040
3041 ospf_poll_send (nbr_nbma);
3042
3043 if (nbr_nbma->v_poll > 0)
3044 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3045 nbr_nbma->v_poll);
3046
3047 return 0;
3048}
3049
3050
3051int
3052ospf_hello_reply_timer (struct thread *thread)
3053{
3054 struct ospf_neighbor *nbr;
3055
3056 nbr = THREAD_ARG (thread);
3057 nbr->t_hello_reply = NULL;
3058
3059 assert (nbr->oi);
3060
3061 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003062 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003063 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3064
3065 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3066
3067 return 0;
3068}
3069
3070/* Send OSPF Hello. */
3071void
3072ospf_hello_send (struct ospf_interface *oi)
3073{
3074 struct ospf_packet *op;
3075 u_int16_t length = OSPF_HEADER_SIZE;
3076
3077 /* If this is passive interface, do not send OSPF Hello. */
3078 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3079 return;
3080
3081 op = ospf_packet_new (oi->ifp->mtu);
3082
3083 /* Prepare OSPF common header. */
3084 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3085
3086 /* Prepare OSPF Hello body. */
3087 length += ospf_make_hello (oi, op->s);
3088
3089 /* Fill OSPF header. */
3090 ospf_fill_header (oi, op->s, length);
3091
3092 /* Set packet length. */
3093 op->length = length;
3094
3095 if (oi->type == OSPF_IFTYPE_NBMA)
3096 {
3097 struct ospf_neighbor *nbr;
3098 struct route_node *rn;
3099
3100 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3101 if ((nbr = rn->info))
3102 if (nbr != oi->nbr_self)
3103 if (nbr->state != NSM_Down)
3104 {
3105 /* RFC 2328 Section 9.5.1
3106 If the router is not eligible to become Designated Router,
3107 it must periodically send Hello Packets to both the
3108 Designated Router and the Backup Designated Router (if they
3109 exist). */
3110 if (PRIORITY(oi) == 0 &&
3111 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3112 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3113 continue;
3114
3115 /* If the router is eligible to become Designated Router, it
3116 must periodically send Hello Packets to all neighbors that
3117 are also eligible. In addition, if the router is itself the
3118 Designated Router or Backup Designated Router, it must also
3119 send periodic Hello Packets to all other neighbors. */
3120
3121 if (nbr->priority == 0 && oi->state == ISM_DROther)
3122 continue;
3123 /* if oi->state == Waiting, send hello to all neighbors */
3124 {
3125 struct ospf_packet *op_dup;
3126
3127 op_dup = ospf_packet_dup(op);
3128 op_dup->dst = nbr->address.u.prefix4;
3129
3130 /* Add packet to the interface output queue. */
3131 ospf_packet_add (oi, op_dup);
3132
paul020709f2003-04-04 02:44:16 +00003133 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003134 }
3135
3136 }
3137 ospf_packet_free (op);
3138 }
3139 else
3140 {
3141 /* Decide destination address. */
3142 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3143 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3144 else
3145 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3146
3147 /* Add packet to the interface output queue. */
3148 ospf_packet_add (oi, op);
3149
3150 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003151 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003152 }
3153}
3154
3155/* Send OSPF Database Description. */
3156void
3157ospf_db_desc_send (struct ospf_neighbor *nbr)
3158{
3159 struct ospf_interface *oi;
3160 struct ospf_packet *op;
3161 u_int16_t length = OSPF_HEADER_SIZE;
3162
3163 oi = nbr->oi;
3164 op = ospf_packet_new (oi->ifp->mtu);
3165
3166 /* Prepare OSPF common header. */
3167 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3168
3169 /* Prepare OSPF Database Description body. */
3170 length += ospf_make_db_desc (oi, nbr, op->s);
3171
3172 /* Fill OSPF header. */
3173 ospf_fill_header (oi, op->s, length);
3174
3175 /* Set packet length. */
3176 op->length = length;
3177
3178 /* Decide destination address. */
3179 op->dst = nbr->address.u.prefix4;
3180
3181 /* Add packet to the interface output queue. */
3182 ospf_packet_add (oi, op);
3183
3184 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003185 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003186
3187 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3188 if (nbr->last_send)
3189 ospf_packet_free (nbr->last_send);
3190 nbr->last_send = ospf_packet_dup (op);
3191 gettimeofday (&nbr->last_send_ts, NULL);
3192}
3193
3194/* Re-send Database Description. */
3195void
3196ospf_db_desc_resend (struct ospf_neighbor *nbr)
3197{
3198 struct ospf_interface *oi;
3199
3200 oi = nbr->oi;
3201
3202 /* Add packet to the interface output queue. */
3203 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3204
3205 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003206 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003207}
3208
3209/* Send Link State Request. */
3210void
3211ospf_ls_req_send (struct ospf_neighbor *nbr)
3212{
3213 struct ospf_interface *oi;
3214 struct ospf_packet *op;
3215 u_int16_t length = OSPF_HEADER_SIZE;
3216
3217 oi = nbr->oi;
3218 op = ospf_packet_new (oi->ifp->mtu);
3219
3220 /* Prepare OSPF common header. */
3221 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3222
3223 /* Prepare OSPF Link State Request body. */
3224 length += ospf_make_ls_req (nbr, op->s);
3225 if (length == OSPF_HEADER_SIZE)
3226 {
3227 ospf_packet_free (op);
3228 return;
3229 }
3230
3231 /* Fill OSPF header. */
3232 ospf_fill_header (oi, op->s, length);
3233
3234 /* Set packet length. */
3235 op->length = length;
3236
3237 /* Decide destination address. */
3238 op->dst = nbr->address.u.prefix4;
3239
3240 /* Add packet to the interface output queue. */
3241 ospf_packet_add (oi, op);
3242
3243 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003244 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003245
3246 /* Add Link State Request Retransmission Timer. */
3247 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3248}
3249
3250/* Send Link State Update with an LSA. */
3251void
3252ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3253 int flag)
3254{
hasso52dc7ee2004-09-23 19:18:23 +00003255 struct list *update;
paul718e3742002-12-13 20:15:29 +00003256
3257 update = list_new ();
3258
3259 listnode_add (update, lsa);
3260 ospf_ls_upd_send (nbr, update, flag);
3261
3262 list_delete (update);
3263}
3264
paul68b73392004-09-12 14:21:37 +00003265/* Determine size for packet. Must be at least big enough to accomodate next
3266 * LSA on list, which may be bigger than MTU size.
3267 *
3268 * Return pointer to new ospf_packet
3269 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3270 * on packet sizes (in which case offending LSA is deleted from update list)
3271 */
3272static struct ospf_packet *
3273ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3274{
3275 struct ospf_lsa *lsa;
3276 struct listnode *ln;
3277 size_t size;
3278 static char warned = 0;
3279
3280 ln = listhead (update);
3281 lsa = getdata (ln);
3282 assert (lsa);
3283 assert (lsa->data);
3284
3285 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3286 > ospf_packet_max (oi))
3287 {
3288 if (!warned)
3289 {
3290 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3291 "will need to fragment. Not optimal. Try divide up"
3292 " your network with areas. Use 'debug ospf packet send'"
3293 " to see details, or look at 'show ip ospf database ..'");
3294 warned = 1;
3295 }
3296
3297 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003298 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003299 " %d bytes originated by %s, will be fragmented!",
3300 inet_ntoa (lsa->data->id),
3301 ntohs (lsa->data->length),
3302 inet_ntoa (lsa->data->adv_router));
3303
3304 /*
3305 * Allocate just enough to fit this LSA only, to avoid including other
3306 * LSAs in fragmented LSA Updates.
3307 */
3308 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3309 + OSPF_LS_UPD_MIN_SIZE;
3310 }
3311 else
3312 size = oi->ifp->mtu;
3313
gdt86f1fd92005-01-10 14:20:43 +00003314 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003315 if (size > OSPF_MAX_PACKET_SIZE)
3316 {
3317 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003318 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003319 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003320 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003321 (long int) size);
paul68b73392004-09-12 14:21:37 +00003322 list_delete_node (update, ln);
3323 return NULL;
3324 }
3325
3326 return ospf_packet_new (size);
3327}
3328
paul718e3742002-12-13 20:15:29 +00003329static void
hasso52dc7ee2004-09-23 19:18:23 +00003330ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003331 struct in_addr addr)
3332{
3333 struct ospf_packet *op;
3334 u_int16_t length = OSPF_HEADER_SIZE;
3335
3336 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003337 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003338
3339 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003340
3341 /* Prepare OSPF common header. */
3342 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3343
paul59ea14c2004-07-14 20:50:36 +00003344 /* Prepare OSPF Link State Update body.
3345 * Includes Type-7 translation.
3346 */
paul718e3742002-12-13 20:15:29 +00003347 length += ospf_make_ls_upd (oi, update, op->s);
3348
3349 /* Fill OSPF header. */
3350 ospf_fill_header (oi, op->s, length);
3351
3352 /* Set packet length. */
3353 op->length = length;
3354
3355 /* Decide destination address. */
3356 op->dst.s_addr = addr.s_addr;
3357
3358 /* Add packet to the interface output queue. */
3359 ospf_packet_add (oi, op);
3360
3361 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003362 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003363}
3364
3365static int
3366ospf_ls_upd_send_queue_event (struct thread *thread)
3367{
3368 struct ospf_interface *oi = THREAD_ARG(thread);
3369 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003370 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003371 struct list *update;
paul68b73392004-09-12 14:21:37 +00003372 char again = 0;
paul718e3742002-12-13 20:15:29 +00003373
3374 oi->t_ls_upd_event = NULL;
3375
3376 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003377 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003378
paul736d3442003-07-24 23:22:57 +00003379 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003380 {
paul736d3442003-07-24 23:22:57 +00003381 rnext = route_next (rn);
3382
paul718e3742002-12-13 20:15:29 +00003383 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003384 continue;
paul68b73392004-09-12 14:21:37 +00003385
3386 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003387
paul48fe13b2004-07-27 17:40:44 +00003388 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003389
paul68b73392004-09-12 14:21:37 +00003390 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003391 if (listcount(update) == 0)
3392 {
3393 list_delete (rn->info);
3394 rn->info = NULL;
3395 route_unlock_node (rn);
3396 }
3397 else
paul68b73392004-09-12 14:21:37 +00003398 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003399 }
3400
3401 if (again != 0)
3402 {
3403 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003404 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003405 " %d nodes to try again, raising new event", again);
3406 oi->t_ls_upd_event =
3407 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003408 }
3409
3410 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003411 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003412
paul718e3742002-12-13 20:15:29 +00003413 return 0;
3414}
3415
3416void
hasso52dc7ee2004-09-23 19:18:23 +00003417ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003418{
3419 struct ospf_interface *oi;
3420 struct prefix_ipv4 p;
3421 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003422 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003423
3424 oi = nbr->oi;
3425
3426 p.family = AF_INET;
3427 p.prefixlen = IPV4_MAX_BITLEN;
3428
3429 /* Decide destination address. */
3430 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3431 p.prefix = oi->vl_data->peer_addr;
3432 else if (flag == OSPF_SEND_PACKET_DIRECT)
3433 p.prefix = nbr->address.u.prefix4;
3434 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3435 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3436 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3437 && (flag == OSPF_SEND_PACKET_INDIRECT))
3438 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003439 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3440 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003441 else
3442 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3443
3444 if (oi->type == OSPF_IFTYPE_NBMA)
3445 {
3446 if (flag == OSPF_SEND_PACKET_INDIRECT)
3447 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3448 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3449 zlog_warn ("* LS-Update is sent to myself.");
3450 }
3451
3452 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3453
3454 if (rn->info == NULL)
3455 rn->info = list_new ();
3456
3457 for (n = listhead (update); n; nextnode (n))
3458 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3459
3460 if (oi->t_ls_upd_event == NULL)
3461 oi->t_ls_upd_event =
3462 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3463}
3464
3465static void
hasso52dc7ee2004-09-23 19:18:23 +00003466ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3467 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003468{
3469 struct ospf_packet *op;
3470 u_int16_t length = OSPF_HEADER_SIZE;
3471
3472 op = ospf_packet_new (oi->ifp->mtu);
3473
3474 /* Prepare OSPF common header. */
3475 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3476
3477 /* Prepare OSPF Link State Acknowledgment body. */
3478 length += ospf_make_ls_ack (oi, ack, op->s);
3479
3480 /* Fill OSPF header. */
3481 ospf_fill_header (oi, op->s, length);
3482
3483 /* Set packet length. */
3484 op->length = length;
3485
3486 /* Set destination IP address. */
3487 op->dst = dst;
3488
3489 /* Add packet to the interface output queue. */
3490 ospf_packet_add (oi, op);
3491
3492 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003493 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003494}
3495
3496static int
3497ospf_ls_ack_send_event (struct thread *thread)
3498{
3499 struct ospf_interface *oi = THREAD_ARG (thread);
3500
3501 oi->t_ls_ack_direct = NULL;
3502
3503 while (listcount (oi->ls_ack_direct.ls_ack))
3504 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3505 oi->ls_ack_direct.dst);
3506
3507 return 0;
3508}
3509
3510void
3511ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3512{
3513 struct ospf_interface *oi = nbr->oi;
3514
3515 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3516 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3517
3518 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3519
3520 if (oi->t_ls_ack_direct == NULL)
3521 oi->t_ls_ack_direct =
3522 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3523}
3524
3525/* Send Link State Acknowledgment delayed. */
3526void
3527ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3528{
3529 struct in_addr dst;
3530
3531 /* Decide destination address. */
3532 /* RFC2328 Section 13.5 On non-broadcast
3533 networks, delayed Link State Acknowledgment packets must be
3534 unicast separately over each adjacency (i.e., neighbor whose
3535 state is >= Exchange). */
3536 if (oi->type == OSPF_IFTYPE_NBMA)
3537 {
3538 struct ospf_neighbor *nbr;
3539 struct route_node *rn;
3540
3541 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3542 if ((nbr = rn->info) != NULL)
3543 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3544 while (listcount (oi->ls_ack))
3545 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3546 return;
3547 }
3548 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3549 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3550 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3551 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3552 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3553 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003554 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3555 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003556 else
3557 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3558
3559 while (listcount (oi->ls_ack))
3560 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3561}