blob: 4700329e1d8ac3bd82acc441dab6f59c4ebcc22e [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)
paul68b73392004-09-12 14:21:37 +0000708 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
ajs6099b3b2004-11-20 02:06:59 +0000709 inet_ntoa (iph.ip_dst), safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000710
paul718e3742002-12-13 20:15:29 +0000711 /* Show debug sending packet. */
712 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
713 {
714 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
715 {
ajs2a42e282004-12-08 18:43:03 +0000716 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000717 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000718 stream_set_getp (op->s, 0);
719 ospf_packet_dump (op->s);
720 }
721
ajs2a42e282004-12-08 18:43:03 +0000722 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000723 ospf_packet_type_str[type], inet_ntoa (op->dst),
724 IF_NAME (oi));
725
726 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000727 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000728 }
729
730 /* Now delete packet from queue. */
731 ospf_packet_delete (oi);
732
733 if (ospf_fifo_head (oi->obuf) == NULL)
734 {
735 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000736 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000737 }
738
739 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000740 if (!list_isempty (ospf->oi_write_q))
741 ospf->t_write =
742 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000743
744 return 0;
745}
746
747/* OSPF Hello message read -- RFC2328 Section 10.5. */
748void
749ospf_hello (struct ip *iph, struct ospf_header *ospfh,
750 struct stream * s, struct ospf_interface *oi, int size)
751{
752 struct ospf_hello *hello;
753 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000754 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000755 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000756
757 /* increment statistics. */
758 oi->hello_in++;
759
760 hello = (struct ospf_hello *) STREAM_PNT (s);
761
762 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000763 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000764 {
765 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
766 {
ajs2a42e282004-12-08 18:43:03 +0000767 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000768 "dropping.",
769 ospf_packet_type_str[ospfh->type],
770 inet_ntoa (iph->ip_src));
771 }
772 return;
773 }
paul718e3742002-12-13 20:15:29 +0000774
775 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000776 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000777 char buf[3][INET_ADDRSTRLEN];
778 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
779 "should not receive hellos on passive interface %s!",
780 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
781 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
782 inet_ntop(AF_INET, &oi->address->u.prefix4,
783 buf[2], sizeof(buf[2])));
784 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
785 {
786 /* Try to fix multicast membership. */
787 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
788 ospf_if_set_multicast(oi);
789 }
paul718e3742002-12-13 20:15:29 +0000790 return;
paulf2c80652002-12-13 21:44:27 +0000791 }
paul718e3742002-12-13 20:15:29 +0000792
793 /* get neighbor prefix. */
794 p.family = AF_INET;
795 p.prefixlen = ip_masklen (hello->network_mask);
796 p.u.prefix4 = iph->ip_src;
797
798 /* Compare network mask. */
799 /* Checking is ignored for Point-to-Point and Virtual link. */
800 if (oi->type != OSPF_IFTYPE_POINTOPOINT
801 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
802 if (oi->address->prefixlen != p.prefixlen)
803 {
804 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
805 inet_ntoa (ospfh->router_id));
806 return;
807 }
808
809 /* Compare Hello Interval. */
810 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
811 {
812 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
813 inet_ntoa (ospfh->router_id));
814 return;
815 }
816
817 /* Compare Router Dead Interval. */
818 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
819 {
820 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
821 inet_ntoa (ospfh->router_id));
822 return;
823 }
824
825 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000826 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000827 inet_ntoa (ospfh->router_id),
828 ospf_options_dump (hello->options));
829
830 /* Compare options. */
831#define REJECT_IF_TBIT_ON 1 /* XXX */
832#ifdef REJECT_IF_TBIT_ON
833 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
834 {
835 /*
836 * This router does not support non-zero TOS.
837 * Drop this Hello packet not to establish neighbor relationship.
838 */
839 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
840 inet_ntoa (ospfh->router_id));
841 return;
842 }
843#endif /* REJECT_IF_TBIT_ON */
844
845#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000846 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000847 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
848 {
849 /*
850 * This router does know the correct usage of O-bit
851 * the bit should be set in DD packet only.
852 */
853 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
854 inet_ntoa (ospfh->router_id));
855#ifdef STRICT_OBIT_USAGE_CHECK
856 return; /* Reject this packet. */
857#else /* STRICT_OBIT_USAGE_CHECK */
858 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
859#endif /* STRICT_OBIT_USAGE_CHECK */
860 }
861#endif /* HAVE_OPAQUE_LSA */
862
863 /* new for NSSA is to ensure that NP is on and E is off */
864
paul718e3742002-12-13 20:15:29 +0000865 if (oi->area->external_routing == OSPF_AREA_NSSA)
866 {
867 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
868 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
869 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
870 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
871 {
872 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
873 return;
874 }
875 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000876 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000877 }
878 else
paul718e3742002-12-13 20:15:29 +0000879 /* The setting of the E-bit found in the Hello Packet's Options
880 field must match this area's ExternalRoutingCapability A
881 mismatch causes processing to stop and the packet to be
882 dropped. The setting of the rest of the bits in the Hello
883 Packet's Options field should be ignored. */
884 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
885 CHECK_FLAG (hello->options, OSPF_OPTION_E))
886 {
ajs3aa8d5f2004-12-11 18:00:06 +0000887 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
888 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000889 return;
890 }
paul718e3742002-12-13 20:15:29 +0000891
pauld3f0d622004-05-05 15:27:15 +0000892 /* get neighbour struct */
893 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
894
895 /* neighbour must be valid, ospf_nbr_get creates if none existed */
896 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000897
898 old_state = nbr->state;
899
900 /* Add event to thread. */
901 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
902
903 /* RFC2328 Section 9.5.1
904 If the router is not eligible to become Designated Router,
905 (snip) It must also send an Hello Packet in reply to an
906 Hello Packet received from any eligible neighbor (other than
907 the current Designated Router and Backup Designated Router). */
908 if (oi->type == OSPF_IFTYPE_NBMA)
909 if (PRIORITY(oi) == 0 && hello->priority > 0
910 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
911 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
912 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
913 OSPF_HELLO_REPLY_DELAY);
914
915 /* on NBMA network type, it happens to receive bidirectional Hello packet
916 without advance 1-Way Received event.
917 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
918 if (oi->type == OSPF_IFTYPE_NBMA &&
919 (old_state == NSM_Down || old_state == NSM_Attempt))
920 {
921 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
922 nbr->priority = hello->priority;
923 nbr->d_router = hello->d_router;
924 nbr->bd_router = hello->bd_router;
925 return;
926 }
927
paul68980082003-03-25 05:07:42 +0000928 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000929 size - OSPF_HELLO_MIN_SIZE))
930 {
931 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
932 nbr->options |= hello->options;
933 }
934 else
935 {
936 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
937 /* Set neighbor information. */
938 nbr->priority = hello->priority;
939 nbr->d_router = hello->d_router;
940 nbr->bd_router = hello->bd_router;
941 return;
942 }
943
944 /* If neighbor itself declares DR and no BDR exists,
945 cause event BackupSeen */
946 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
947 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
948 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
949
950 /* neighbor itself declares BDR. */
951 if (oi->state == ISM_Waiting &&
952 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
953 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
954
955 /* had not previously. */
956 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
957 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
958 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
959 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
960 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
961
962 /* had not previously. */
963 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
964 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
965 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
966 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
967 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
968
969 /* Neighbor priority check. */
970 if (nbr->priority >= 0 && nbr->priority != hello->priority)
971 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
972
973 /* Set neighbor information. */
974 nbr->priority = hello->priority;
975 nbr->d_router = hello->d_router;
976 nbr->bd_router = hello->bd_router;
977}
978
979/* Save DD flags/options/Seqnum received. */
980void
981ospf_db_desc_save_current (struct ospf_neighbor *nbr,
982 struct ospf_db_desc *dd)
983{
984 nbr->last_recv.flags = dd->flags;
985 nbr->last_recv.options = dd->options;
986 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
987}
988
989/* Process rest of DD packet. */
990static void
991ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
992 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
993 u_int16_t size)
994{
995 struct ospf_lsa *new, *find;
996 struct lsa_header *lsah;
997
998 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
999 for (size -= OSPF_DB_DESC_MIN_SIZE;
1000 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1001 {
1002 lsah = (struct lsa_header *) STREAM_PNT (s);
1003 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1004
1005 /* Unknown LS type. */
1006 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1007 {
ajsbec595a2004-11-30 22:38:43 +00001008 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001009 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1010 return;
1011 }
1012
1013#ifdef HAVE_OPAQUE_LSA
1014 if (IS_OPAQUE_LSA (lsah->type)
1015 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1016 {
1017 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1018 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1019 return;
1020 }
1021#endif /* HAVE_OPAQUE_LSA */
1022
1023 switch (lsah->type)
1024 {
1025 case OSPF_AS_EXTERNAL_LSA:
1026#ifdef HAVE_OPAQUE_LSA
1027 case OSPF_OPAQUE_AS_LSA:
1028#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001029 /* Check for stub area. Reject if AS-External from stub but
1030 allow if from NSSA. */
1031 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001032 {
1033 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1034 lsah->type, inet_ntoa (lsah->id),
1035 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1036 "STUB" : "NSSA");
1037 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1038 return;
1039 }
1040 break;
1041 default:
1042 break;
1043 }
1044
1045 /* Create LS-request object. */
1046 new = ospf_ls_request_new (lsah);
1047
1048 /* Lookup received LSA, then add LS request list. */
1049 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1050 if (!find || ospf_lsa_more_recent (find, new) < 0)
1051 {
1052 ospf_ls_request_add (nbr, new);
1053 ospf_lsa_discard (new);
1054 }
1055 else
1056 {
1057 /* Received LSA is not recent. */
1058 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001059 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001060 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1061 ospf_lsa_discard (new);
1062 continue;
1063 }
1064 }
1065
1066 /* Master */
1067 if (IS_SET_DD_MS (nbr->dd_flags))
1068 {
1069 nbr->dd_seqnum++;
1070 /* Entire DD packet sent. */
1071 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1072 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1073 else
1074 /* Send new DD packet. */
1075 ospf_db_desc_send (nbr);
1076 }
1077 /* Slave */
1078 else
1079 {
1080 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1081
1082 /* When master's more flags is not set. */
1083 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1084 {
1085 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1086 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1087 }
1088
ajsbec595a2004-11-30 22:38:43 +00001089 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001090 ospf_db_desc_send (nbr);
1091 }
1092
1093 /* Save received neighbor values from DD. */
1094 ospf_db_desc_save_current (nbr, dd);
1095}
1096
1097int
1098ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1099{
1100 /* Is DD duplicated? */
1101 if (dd->options == nbr->last_recv.options &&
1102 dd->flags == nbr->last_recv.flags &&
1103 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1104 return 1;
1105
1106 return 0;
1107}
1108
1109/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001110static void
paul718e3742002-12-13 20:15:29 +00001111ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1112 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1113{
1114 struct ospf_db_desc *dd;
1115 struct ospf_neighbor *nbr;
1116
1117 /* Increment statistics. */
1118 oi->db_desc_in++;
1119
1120 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001121
pauld3f0d622004-05-05 15:27:15 +00001122 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001123 if (nbr == NULL)
1124 {
1125 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1126 inet_ntoa (ospfh->router_id));
1127 return;
1128 }
1129
1130 /* Check MTU. */
1131 if (ntohs (dd->mtu) > oi->ifp->mtu)
1132 {
ajs3aa8d5f2004-12-11 18:00:06 +00001133 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1134 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1135 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001136 return;
1137 }
1138
pauld363df22003-06-19 00:26:34 +00001139 /*
1140 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1141 * required. In fact at least JunOS sends DD packets with P bit clear.
1142 * Until proper solution is developped, this hack should help.
1143 *
1144 * Update: According to the RFCs, N bit is specified /only/ for Hello
1145 * options, unfortunately its use in DD options is not specified. Hence some
1146 * implementations follow E-bit semantics and set it in DD options, and some
1147 * treat it as unspecified and hence follow the directive "default for
1148 * options is clear", ie unset.
1149 *
1150 * Reset the flag, as ospfd follows E-bit semantics.
1151 */
1152 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1153 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1154 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1155 {
1156 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001157 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001158 inet_ntoa (nbr->router_id) );
1159 SET_FLAG (dd->options, OSPF_OPTION_NP);
1160 }
pauld363df22003-06-19 00:26:34 +00001161
paul718e3742002-12-13 20:15:29 +00001162#ifdef REJECT_IF_TBIT_ON
1163 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1164 {
1165 /*
1166 * In Hello protocol, optional capability must have checked
1167 * to prevent this T-bit enabled router be my neighbor.
1168 */
1169 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1170 return;
1171 }
1172#endif /* REJECT_IF_TBIT_ON */
1173
1174#ifdef HAVE_OPAQUE_LSA
1175 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001176 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001177 {
1178 /*
1179 * This node is not configured to handle O-bit, for now.
1180 * Clear it to ignore unsupported capability proposed by neighbor.
1181 */
1182 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1183 }
1184#endif /* HAVE_OPAQUE_LSA */
1185
1186 /* Process DD packet by neighbor status. */
1187 switch (nbr->state)
1188 {
1189 case NSM_Down:
1190 case NSM_Attempt:
1191 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001192 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001193 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001194 LOOKUP (ospf_nsm_state_msg, nbr->state));
1195 break;
1196 case NSM_Init:
1197 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1198 /* If the new state is ExStart, the processing of the current
1199 packet should then continue in this new state by falling
1200 through to case ExStart below. */
1201 if (nbr->state != NSM_ExStart)
1202 break;
1203 case NSM_ExStart:
1204 /* Initial DBD */
1205 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1206 (size == OSPF_DB_DESC_MIN_SIZE))
1207 {
paul68980082003-03-25 05:07:42 +00001208 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001209 {
1210 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001211 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001212 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001213 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1214 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1215 }
1216 else
1217 {
1218 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001219 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1220 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001221 break;
1222 }
1223 }
1224 /* Ack from the Slave */
1225 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1226 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001227 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001228 {
ajs17eaa722004-12-29 21:04:48 +00001229 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001230 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001231 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1232 }
1233 else
1234 {
ajs3aa8d5f2004-12-11 18:00:06 +00001235 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1236 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001237 break;
1238 }
1239
1240 /* This is where the real Options are saved */
1241 nbr->options = dd->options;
1242
1243#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001244 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001245 {
1246 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001247 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001248 inet_ntoa (nbr->router_id),
1249 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1250
1251 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1252 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1253 {
1254 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1255 /* This situation is undesirable, but not a real error. */
1256 }
1257 }
1258#endif /* HAVE_OPAQUE_LSA */
1259
1260 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1261
1262 /* continue processing rest of packet. */
1263 ospf_db_desc_proc (s, oi, nbr, dd, size);
1264 break;
1265 case NSM_Exchange:
1266 if (ospf_db_desc_is_dup (dd, nbr))
1267 {
1268 if (IS_SET_DD_MS (nbr->dd_flags))
1269 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001270 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1271 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001272 else
1273 /* Slave: cause to retransmit the last Database Description. */
1274 {
ajs3aa8d5f2004-12-11 18:00:06 +00001275 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1276 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001277 ospf_db_desc_resend (nbr);
1278 }
1279 break;
1280 }
1281
1282 /* Otherwise DD packet should be checked. */
1283 /* Check Master/Slave bit mismatch */
1284 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1285 {
ajs3aa8d5f2004-12-11 18:00:06 +00001286 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1287 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001288 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1289 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001290 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001291 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001292 break;
1293 }
1294
1295 /* Check initialize bit is set. */
1296 if (IS_SET_DD_I (dd->flags))
1297 {
ajs3aa8d5f2004-12-11 18:00:06 +00001298 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1299 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001300 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1301 break;
1302 }
1303
1304 /* Check DD Options. */
1305 if (dd->options != nbr->options)
1306 {
1307#ifdef ORIGINAL_CODING
1308 /* Save the new options for debugging */
1309 nbr->options = dd->options;
1310#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001311 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1312 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001313 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1314 break;
1315 }
1316
1317 /* Check DD sequence number. */
1318 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1319 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1320 (!IS_SET_DD_MS (nbr->dd_flags) &&
1321 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1322 {
ajs3aa8d5f2004-12-11 18:00:06 +00001323 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1324 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001325 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1326 break;
1327 }
1328
1329 /* Continue processing rest of packet. */
1330 ospf_db_desc_proc (s, oi, nbr, dd, size);
1331 break;
1332 case NSM_Loading:
1333 case NSM_Full:
1334 if (ospf_db_desc_is_dup (dd, nbr))
1335 {
1336 if (IS_SET_DD_MS (nbr->dd_flags))
1337 {
1338 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001339 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1340 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001341 break;
1342 }
1343 else
1344 {
1345 struct timeval t, now;
1346 gettimeofday (&now, NULL);
1347 t = tv_sub (now, nbr->last_send_ts);
1348 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1349 {
1350 /* In states Loading and Full the slave must resend
1351 its last Database Description packet in response to
1352 duplicate Database Description packets received
1353 from the master. For this reason the slave must
1354 wait RouterDeadInterval seconds before freeing the
1355 last Database Description packet. Reception of a
1356 Database Description packet from the master after
1357 this interval will generate a SeqNumberMismatch
1358 neighbor event. RFC2328 Section 10.8 */
1359 ospf_db_desc_resend (nbr);
1360 break;
1361 }
1362 }
1363 }
1364
1365 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1366 break;
1367 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001368 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1369 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001370 break;
1371 }
1372}
1373
1374#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1375
1376/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1377void
1378ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1379 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1380{
1381 struct ospf_neighbor *nbr;
1382 u_int32_t ls_type;
1383 struct in_addr ls_id;
1384 struct in_addr adv_router;
1385 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001386 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001387 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001388
1389 /* Increment statistics. */
1390 oi->ls_req_in++;
1391
pauld3f0d622004-05-05 15:27:15 +00001392 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001393 if (nbr == NULL)
1394 {
1395 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1396 inet_ntoa (ospfh->router_id));
1397 return;
1398 }
1399
1400 /* Neighbor State should be Exchange or later. */
1401 if (nbr->state != NSM_Exchange &&
1402 nbr->state != NSM_Loading &&
1403 nbr->state != NSM_Full)
1404 {
ajsbec595a2004-11-30 22:38:43 +00001405 zlog_warn ("Link State Request received from %s: "
1406 "Neighbor state is %s, packet discarded.",
1407 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001408 LOOKUP (ospf_nsm_state_msg, nbr->state));
1409 return;
1410 }
1411
1412 /* Send Link State Update for ALL requested LSAs. */
1413 ls_upd = list_new ();
1414 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1415
1416 while (size >= OSPF_LSA_KEY_SIZE)
1417 {
1418 /* Get one slice of Link State Request. */
1419 ls_type = stream_getl (s);
1420 ls_id.s_addr = stream_get_ipv4 (s);
1421 adv_router.s_addr = stream_get_ipv4 (s);
1422
1423 /* Verify LSA type. */
1424 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1425 {
1426 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1427 list_delete (ls_upd);
1428 return;
1429 }
1430
1431 /* Search proper LSA in LSDB. */
1432 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1433 if (find == NULL)
1434 {
1435 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1436 list_delete (ls_upd);
1437 return;
1438 }
1439
gdt86f1fd92005-01-10 14:20:43 +00001440 /* Packet overflows MTU size, send immediately. */
1441 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001442 {
1443 if (oi->type == OSPF_IFTYPE_NBMA)
1444 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1445 else
1446 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1447
1448 /* Only remove list contents. Keep ls_upd. */
1449 list_delete_all_node (ls_upd);
1450
1451 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1452 }
1453
1454 /* Append LSA to update list. */
1455 listnode_add (ls_upd, find);
1456 length += ntohs (find->data->length);
1457
1458 size -= OSPF_LSA_KEY_SIZE;
1459 }
1460
1461 /* Send rest of Link State Update. */
1462 if (listcount (ls_upd) > 0)
1463 {
1464 if (oi->type == OSPF_IFTYPE_NBMA)
1465 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1466 else
1467 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1468
1469 list_delete (ls_upd);
1470 }
1471 else
1472 list_free (ls_upd);
1473}
1474
1475/* Get the list of LSAs from Link State Update packet.
1476 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001477static struct list *
paul718e3742002-12-13 20:15:29 +00001478ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1479 struct ospf_interface *oi, size_t size)
1480{
1481 u_int16_t count, sum;
1482 u_int32_t length;
1483 struct lsa_header *lsah;
1484 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001485 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001486
1487 lsas = list_new ();
1488
1489 count = stream_getl (s);
1490 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1491
1492 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1493 size -= length, stream_forward (s, length), count--)
1494 {
1495 lsah = (struct lsa_header *) STREAM_PNT (s);
1496 length = ntohs (lsah->length);
1497
1498 if (length > size)
1499 {
1500 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1501 break;
1502 }
1503
1504 /* Validate the LSA's LS checksum. */
1505 sum = lsah->checksum;
1506 if (sum != ospf_lsa_checksum (lsah))
1507 {
1508 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1509 sum, lsah->checksum);
1510 continue;
1511 }
1512
1513 /* Examine the LSA's LS type. */
1514 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1515 {
1516 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1517 continue;
1518 }
1519
1520 /*
1521 * What if the received LSA's age is greater than MaxAge?
1522 * Treat it as a MaxAge case -- endo.
1523 */
1524 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1525 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1526
1527#ifdef HAVE_OPAQUE_LSA
1528 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1529 {
1530#ifdef STRICT_OBIT_USAGE_CHECK
1531 if ((IS_OPAQUE_LSA(lsah->type) &&
1532 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1533 || (! IS_OPAQUE_LSA(lsah->type) &&
1534 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1535 {
1536 /*
1537 * This neighbor must know the exact usage of O-bit;
1538 * the bit will be set in Type-9,10,11 LSAs only.
1539 */
1540 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1541 continue;
1542 }
1543#endif /* STRICT_OBIT_USAGE_CHECK */
1544
1545 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1546 if (lsah->type == OSPF_OPAQUE_AS_LSA
1547 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1548 {
1549 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001550 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 +00001551 continue;
1552 }
1553 }
1554 else if (IS_OPAQUE_LSA(lsah->type))
1555 {
1556 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1557 continue;
1558 }
1559#endif /* HAVE_OPAQUE_LSA */
1560
1561 /* Create OSPF LSA instance. */
1562 lsa = ospf_lsa_new ();
1563
1564 /* We may wish to put some error checking if type NSSA comes in
1565 and area not in NSSA mode */
1566 switch (lsah->type)
1567 {
1568 case OSPF_AS_EXTERNAL_LSA:
1569#ifdef HAVE_OPAQUE_LSA
1570 case OSPF_OPAQUE_AS_LSA:
1571 lsa->area = NULL;
1572 break;
1573 case OSPF_OPAQUE_LINK_LSA:
1574 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1575 /* Fallthrough */
1576#endif /* HAVE_OPAQUE_LSA */
1577 default:
1578 lsa->area = oi->area;
1579 break;
1580 }
1581
1582 lsa->data = ospf_lsa_data_new (length);
1583 memcpy (lsa->data, lsah, length);
1584
1585 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001586 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001587 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1588 listnode_add (lsas, lsa);
1589 }
1590
1591 return lsas;
1592}
1593
1594/* Cleanup Update list. */
1595void
hasso52dc7ee2004-09-23 19:18:23 +00001596ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001597{
hasso52dc7ee2004-09-23 19:18:23 +00001598 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001599 struct ospf_lsa *lsa;
1600
1601 for (node = listhead (lsas); node; nextnode (node))
1602 if ((lsa = getdata (node)) != NULL)
1603 ospf_lsa_discard (lsa);
1604
1605 list_delete (lsas);
1606}
1607
1608/* OSPF Link State Update message read -- RFC2328 Section 13. */
1609void
1610ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1611 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1612{
1613 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001614 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001615#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001616 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001617#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001618 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001619 struct ospf_lsa *lsa = NULL;
1620 /* unsigned long ls_req_found = 0; */
1621
1622 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1623
1624 /* Increment statistics. */
1625 oi->ls_upd_in++;
1626
1627 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001628 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001629 if (nbr == NULL)
1630 {
1631 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1632 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1633 return;
1634 }
1635
1636 /* Check neighbor state. */
1637 if (nbr->state < NSM_Exchange)
1638 {
ajs3aa8d5f2004-12-11 18:00:06 +00001639 zlog_warn ("Link State Update: "
1640 "Neighbor[%s] state %s is less than Exchange",
1641 inet_ntoa (ospfh->router_id),
1642 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001643 return;
1644 }
1645
1646 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1647 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1648 * of section 13.
1649 */
1650 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1651
1652#ifdef HAVE_OPAQUE_LSA
1653 /*
1654 * Prepare two kinds of lists to clean up unwanted self-originated
1655 * Opaque-LSAs from the routing domain as soon as possible.
1656 */
1657 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1658 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1659
1660 /*
1661 * If self-originated Opaque-LSAs that have flooded before restart
1662 * are contained in the received LSUpd message, corresponding LSReq
1663 * messages to be sent may have to be modified.
1664 * To eliminate possible race conditions such that flushing and normal
1665 * updating for the same LSA would take place alternately, this trick
1666 * must be done before entering to the loop below.
1667 */
1668 ospf_opaque_adjust_lsreq (nbr, lsas);
1669#endif /* HAVE_OPAQUE_LSA */
1670
1671#define DISCARD_LSA(L,N) {\
1672 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001673 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 +00001674 ospf_lsa_discard (L); \
1675 continue; }
1676
1677 /* Process each LSA received in the one packet. */
1678 for (node = listhead (lsas); node; node = next)
1679 {
1680 struct ospf_lsa *ls_ret, *current;
1681 int ret = 1;
1682
1683 next = node->next;
1684
1685 lsa = getdata (node);
1686
paul718e3742002-12-13 20:15:29 +00001687 if (IS_DEBUG_OSPF_NSSA)
1688 {
1689 char buf1[INET_ADDRSTRLEN];
1690 char buf2[INET_ADDRSTRLEN];
1691 char buf3[INET_ADDRSTRLEN];
1692
ajs2a42e282004-12-08 18:43:03 +00001693 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001694 lsa->data->type,
1695 inet_ntop (AF_INET, &ospfh->router_id,
1696 buf1, INET_ADDRSTRLEN),
1697 inet_ntop (AF_INET, &lsa->data->id,
1698 buf2, INET_ADDRSTRLEN),
1699 inet_ntop (AF_INET, &lsa->data->adv_router,
1700 buf3, INET_ADDRSTRLEN));
1701 }
paul718e3742002-12-13 20:15:29 +00001702
1703 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1704
1705 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1706
1707 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1708
1709 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1710
1711 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1712
1713 /* Do take in Type-7's if we are an NSSA */
1714
1715 /* If we are also an ABR, later translate them to a Type-5 packet */
1716
1717 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1718 translate them to a separate Type-5 packet. */
1719
1720 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1721 /* Reject from STUB or NSSA */
1722 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1723 {
1724 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001725 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001726 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001727 }
1728
paul718e3742002-12-13 20:15:29 +00001729 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1730 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1731 {
1732 DISCARD_LSA (lsa,2);
1733 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001734 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001735 }
paul718e3742002-12-13 20:15:29 +00001736
1737 /* Find the LSA in the current database. */
1738
1739 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1740
1741 /* If the LSA's LS age is equal to MaxAge, and there is currently
1742 no instance of the LSA in the router's link state database,
1743 and none of router's neighbors are in states Exchange or Loading,
1744 then take the following actions. */
1745
1746 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001747 (ospf_nbr_count (oi, NSM_Exchange) +
1748 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001749 {
1750 /* Response Link State Acknowledgment. */
1751 ospf_ls_ack_send (nbr, lsa);
1752
1753 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001754 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1755 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001756 DISCARD_LSA (lsa, 3);
1757 }
1758
1759#ifdef HAVE_OPAQUE_LSA
1760 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001761 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001762 {
1763 /*
1764 * Even if initial flushing seems to be completed, there might
1765 * be a case that self-originated LSA with MaxAge still remain
1766 * in the routing domain.
1767 * Just send an LSAck message to cease retransmission.
1768 */
1769 if (IS_LSA_MAXAGE (lsa))
1770 {
1771 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1772 ospf_ls_ack_send (nbr, lsa);
1773 ospf_lsa_discard (lsa);
1774
1775 if (current != NULL && ! IS_LSA_MAXAGE (current))
1776 ospf_opaque_lsa_refresh_schedule (current);
1777 continue;
1778 }
1779
1780 /*
1781 * If an instance of self-originated Opaque-LSA is not found
1782 * in the LSDB, there are some possible cases here.
1783 *
1784 * 1) This node lost opaque-capability after restart.
1785 * 2) Else, a part of opaque-type is no more supported.
1786 * 3) Else, a part of opaque-id is no more supported.
1787 *
1788 * Anyway, it is still this node's responsibility to flush it.
1789 * Otherwise, the LSA instance remains in the routing domain
1790 * until its age reaches to MaxAge.
1791 */
1792 if (current == NULL)
1793 {
1794 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001795 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001796
1797 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1798 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1799 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1800 continue;
1801 }
1802 }
1803#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001804 /* It might be happen that received LSA is self-originated network LSA, but
1805 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1806 * Link State ID is one of the router's own IP interface addresses but whose
1807 * Advertising Router is not equal to the router's own Router ID
1808 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1809 */
1810
1811 if(lsa->data->type == OSPF_NETWORK_LSA)
1812 {
hasso52dc7ee2004-09-23 19:18:23 +00001813 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001814 int Flag = 0;
1815
1816 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1817 {
1818 struct ospf_interface *out_if = getdata(oi_node);
1819 if(out_if == NULL)
1820 break;
1821
1822 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1823 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1824 {
1825 if(out_if->network_lsa_self)
1826 {
1827 ospf_lsa_flush_area(lsa,out_if->area);
1828 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001829 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001830 lsa, (int) lsa->data->type);
1831 ospf_lsa_discard (lsa);
1832 Flag = 1;
1833 }
1834 break;
1835 }
1836 }
1837 if(Flag)
1838 continue;
1839 }
paul718e3742002-12-13 20:15:29 +00001840
1841 /* (5) Find the instance of this LSA that is currently contained
1842 in the router's link state database. If there is no
1843 database copy, or the received LSA is more recent than
1844 the database copy the following steps must be performed. */
1845
1846 if (current == NULL ||
1847 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1848 {
1849 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001850 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001851 DISCARD_LSA (lsa, 4);
1852 continue;
1853 }
1854
1855 /* (6) Else, If there is an instance of the LSA on the sending
1856 neighbor's Link state request list, an error has occurred in
1857 the Database Exchange process. In this case, restart the
1858 Database Exchange process by generating the neighbor event
1859 BadLSReq for the sending neighbor and stop processing the
1860 Link State Update packet. */
1861
1862 if (ospf_ls_request_lookup (nbr, lsa))
1863 {
1864 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001865 zlog_warn("LSA[%s] instance exists on Link state request list",
1866 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001867
1868 /* Clean list of LSAs. */
1869 ospf_upd_list_clean (lsas);
1870 /* this lsa is not on lsas list already. */
1871 ospf_lsa_discard (lsa);
1872#ifdef HAVE_OPAQUE_LSA
1873 list_delete (mylsa_acks);
1874 list_delete (mylsa_upds);
1875#endif /* HAVE_OPAQUE_LSA */
1876 return;
1877 }
1878
1879 /* If the received LSA is the same instance as the database copy
1880 (i.e., neither one is more recent) the following two steps
1881 should be performed: */
1882
1883 if (ret == 0)
1884 {
1885 /* If the LSA is listed in the Link state retransmission list
1886 for the receiving adjacency, the router itself is expecting
1887 an acknowledgment for this LSA. The router should treat the
1888 received LSA as an acknowledgment by removing the LSA from
1889 the Link state retransmission list. This is termed an
1890 "implied acknowledgment". */
1891
1892 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1893
1894 if (ls_ret != NULL)
1895 {
1896 ospf_ls_retransmit_delete (nbr, ls_ret);
1897
1898 /* Delayed acknowledgment sent if advertisement received
1899 from Designated Router, otherwise do nothing. */
1900 if (oi->state == ISM_Backup)
1901 if (NBR_IS_DR (nbr))
1902 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1903
1904 DISCARD_LSA (lsa, 5);
1905 }
1906 else
1907 /* Acknowledge the receipt of the LSA by sending a
1908 Link State Acknowledgment packet back out the receiving
1909 interface. */
1910 {
1911 ospf_ls_ack_send (nbr, lsa);
1912 DISCARD_LSA (lsa, 6);
1913 }
1914 }
1915
1916 /* The database copy is more recent. If the database copy
1917 has LS age equal to MaxAge and LS sequence number equal to
1918 MaxSequenceNumber, simply discard the received LSA without
1919 acknowledging it. (In this case, the LSA's LS sequence number is
1920 wrapping, and the MaxSequenceNumber LSA must be completely
1921 flushed before any new LSA instance can be introduced). */
1922
1923 else if (ret > 0) /* Database copy is more recent */
1924 {
1925 if (IS_LSA_MAXAGE (current) &&
1926 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1927 {
1928 DISCARD_LSA (lsa, 7);
1929 }
1930 /* Otherwise, as long as the database copy has not been sent in a
1931 Link State Update within the last MinLSArrival seconds, send the
1932 database copy back to the sending neighbor, encapsulated within
1933 a Link State Update Packet. The Link State Update Packet should
1934 be sent directly to the neighbor. In so doing, do not put the
1935 database copy of the LSA on the neighbor's link state
1936 retransmission list, and do not acknowledge the received (less
1937 recent) LSA instance. */
1938 else
1939 {
1940 struct timeval now;
1941
1942 gettimeofday (&now, NULL);
1943
1944 if (tv_cmp (tv_sub (now, current->tv_orig),
1945 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1946 /* Trap NSSA type later.*/
1947 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1948 DISCARD_LSA (lsa, 8);
1949 }
1950 }
1951 }
1952
1953#ifdef HAVE_OPAQUE_LSA
1954 /*
1955 * Now that previously originated Opaque-LSAs those which not yet
1956 * installed into LSDB are captured, take several steps to clear
1957 * them completely from the routing domain, before proceeding to
1958 * origination for the current target Opaque-LSAs.
1959 */
1960 while (listcount (mylsa_acks) > 0)
1961 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1962
1963 if (listcount (mylsa_upds) > 0)
1964 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1965
1966 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001967 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001968#endif /* HAVE_OPAQUE_LSA */
1969
1970 assert (listcount (lsas) == 0);
1971 list_delete (lsas);
1972}
1973
1974/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1975void
1976ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1977 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1978{
1979 struct ospf_neighbor *nbr;
1980#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001981 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001982#endif /* HAVE_OPAQUE_LSA */
1983
1984 /* increment statistics. */
1985 oi->ls_ack_in++;
1986
pauld3f0d622004-05-05 15:27:15 +00001987 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001988 if (nbr == NULL)
1989 {
1990 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1991 inet_ntoa (ospfh->router_id));
1992 return;
1993 }
1994
1995 if (nbr->state < NSM_Exchange)
1996 {
ajs3aa8d5f2004-12-11 18:00:06 +00001997 zlog_warn ("Link State Acknowledgment: "
1998 "Neighbor[%s] state %s is less than Exchange",
1999 inet_ntoa (ospfh->router_id),
2000 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002001 return;
2002 }
2003
2004#ifdef HAVE_OPAQUE_LSA
2005 opaque_acks = list_new ();
2006#endif /* HAVE_OPAQUE_LSA */
2007
2008 while (size >= OSPF_LSA_HEADER_SIZE)
2009 {
2010 struct ospf_lsa *lsa, *lsr;
2011
2012 lsa = ospf_lsa_new ();
2013 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2014
2015 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2016 size -= OSPF_LSA_HEADER_SIZE;
2017 stream_forward (s, OSPF_LSA_HEADER_SIZE);
2018
2019 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2020 {
2021 lsa->data = NULL;
2022 ospf_lsa_discard (lsa);
2023 continue;
2024 }
2025
2026 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2027
2028 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2029 {
2030#ifdef HAVE_OPAQUE_LSA
2031 /* Keep this LSA entry for later reference. */
2032 if (IS_OPAQUE_LSA (lsr->data->type))
2033 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2034#endif /* HAVE_OPAQUE_LSA */
2035
2036 ospf_ls_retransmit_delete (nbr, lsr);
2037 }
2038
2039 lsa->data = NULL;
2040 ospf_lsa_discard (lsa);
2041 }
2042
2043#ifdef HAVE_OPAQUE_LSA
2044 if (listcount (opaque_acks) > 0)
2045 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2046
2047 list_delete (opaque_acks);
2048 return;
2049#endif /* HAVE_OPAQUE_LSA */
2050}
2051
2052struct stream *
2053ospf_recv_packet (int fd, struct interface **ifp)
2054{
2055 int ret;
2056 struct ip iph;
2057 u_int16_t ip_len;
2058 struct stream *ibuf;
2059 unsigned int ifindex = 0;
2060 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002061 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002062 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002063 struct msghdr msgh;
2064
paul68defd62004-09-27 07:27:13 +00002065 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002066 msgh.msg_iov = &iov;
2067 msgh.msg_iovlen = 1;
2068 msgh.msg_control = (caddr_t) buff;
2069 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002070
paul718e3742002-12-13 20:15:29 +00002071 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2072
2073 if (ret != sizeof (iph))
2074 {
2075 zlog_warn ("ospf_recv_packet packet smaller than ip header");
gdtbe210242004-12-29 20:12:59 +00002076 /* XXX: We peeked, and thus perhaps should discard this packet. */
paul718e3742002-12-13 20:15:29 +00002077 return NULL;
2078 }
paul18b12c32004-10-05 14:38:29 +00002079
2080 sockopt_iphdrincl_swab_systoh (&iph);
2081
paul6b333612004-10-11 10:11:25 +00002082 ip_len = iph.ip_len;
2083
paul239aecc2003-12-08 10:34:54 +00002084#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002085 /*
2086 * Kernel network code touches incoming IP header parameters,
2087 * before protocol specific processing.
2088 *
2089 * 1) Convert byteorder to host representation.
2090 * --> ip_len, ip_id, ip_off
2091 *
2092 * 2) Adjust ip_len to strip IP header size!
2093 * --> If user process receives entire IP packet via RAW
2094 * socket, it must consider adding IP header size to
2095 * the "ip_len" field of "ip" structure.
2096 *
2097 * For more details, see <netinet/ip_input.c>.
2098 */
2099 ip_len = ip_len + (iph.ip_hl << 2);
2100#endif
2101
2102 ibuf = stream_new (ip_len);
2103 iov.iov_base = STREAM_DATA (ibuf);
2104 iov.iov_len = ip_len;
2105 ret = recvmsg (fd, &msgh, 0);
2106
paul863082d2004-08-19 04:43:43 +00002107 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002108
2109 *ifp = if_lookup_by_index (ifindex);
2110
2111 if (ret != ip_len)
2112 {
2113 zlog_warn ("ospf_recv_packet short read. "
2114 "ip_len %d bytes read %d", ip_len, ret);
2115 stream_free (ibuf);
2116 return NULL;
2117 }
2118
2119 return ibuf;
2120}
2121
2122struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002123ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002124 struct ip *iph, struct ospf_header *ospfh)
2125{
2126 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002127 struct ospf_vl_data *vl_data;
2128 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002129 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002130
2131 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2132 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002133 return NULL;
paul718e3742002-12-13 20:15:29 +00002134
pauld3f0d622004-05-05 15:27:15 +00002135 /* look for local OSPF interface matching the destination
2136 * to determine Area ID. We presume therefore the destination address
2137 * is unique, or at least (for "unnumbered" links), not used in other
2138 * areas
2139 */
2140 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2141 iph->ip_dst)) == NULL)
2142 return NULL;
paul718e3742002-12-13 20:15:29 +00002143
paul020709f2003-04-04 02:44:16 +00002144 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002145 {
2146 if ((vl_data = getdata (node)) == NULL)
2147 continue;
2148
paul020709f2003-04-04 02:44:16 +00002149 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002150 if (!vl_area)
2151 continue;
2152
2153 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2154 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2155 {
2156 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002157 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002158 IF_NAME (vl_data->vl_oi));
2159 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2160 {
2161 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002162 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002163 return NULL;
2164 }
2165
2166 return vl_data->vl_oi;
2167 }
2168 }
2169
2170 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002171 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002172
pauld3f0d622004-05-05 15:27:15 +00002173 return NULL;
paul718e3742002-12-13 20:15:29 +00002174}
2175
2176int
2177ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2178{
2179 /* Check match the Area ID of the receiving interface. */
2180 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2181 return 1;
2182
2183 return 0;
2184}
2185
2186/* Unbound socket will accept any Raw IP packets if proto is matched.
2187 To prevent it, compare src IP address and i/f address with masking
2188 i/f network mask. */
2189int
2190ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2191{
2192 struct in_addr mask, me, him;
2193
2194 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2195 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2196 return 1;
2197
2198 masklen2ip (oi->address->prefixlen, &mask);
2199
2200 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2201 him.s_addr = ip_src.s_addr & mask.s_addr;
2202
2203 if (IPV4_ADDR_SAME (&me, &him))
2204 return 1;
2205
2206 return 0;
2207}
2208
2209int
2210ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2211 struct ospf_header *ospfh)
2212{
2213 int ret = 0;
2214 struct crypt_key *ck;
2215
2216 switch (ntohs (ospfh->auth_type))
2217 {
2218 case OSPF_AUTH_NULL:
2219 ret = 1;
2220 break;
2221 case OSPF_AUTH_SIMPLE:
2222 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2223 ret = 1;
2224 else
2225 ret = 0;
2226 break;
2227 case OSPF_AUTH_CRYPTOGRAPHIC:
2228 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2229 {
2230 ret = 0;
2231 break;
2232 }
2233
2234 /* This is very basic, the digest processing is elsewhere */
2235 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2236 ospfh->u.crypt.key_id == ck->key_id &&
2237 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2238 ret = 1;
2239 else
2240 ret = 0;
2241 break;
2242 default:
2243 ret = 0;
2244 break;
2245 }
2246
2247 return ret;
2248}
2249
2250int
2251ospf_check_sum (struct ospf_header *ospfh)
2252{
2253 u_int32_t ret;
2254 u_int16_t sum;
2255 int in_cksum (void *ptr, int nbytes);
2256
2257 /* clear auth_data for checksum. */
2258 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2259
2260 /* keep checksum and clear. */
2261 sum = ospfh->checksum;
2262 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2263
2264 /* calculate checksum. */
2265 ret = in_cksum (ospfh, ntohs (ospfh->length));
2266
2267 if (ret != sum)
2268 {
2269 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2270 ret, sum);
2271 return 0;
2272 }
2273
2274 return 1;
2275}
2276
2277/* OSPF Header verification. */
2278int
2279ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2280 struct ip *iph, struct ospf_header *ospfh)
2281{
2282 /* check version. */
2283 if (ospfh->version != OSPF_VERSION)
2284 {
2285 zlog_warn ("interface %s: ospf_read version number mismatch.",
2286 IF_NAME (oi));
2287 return -1;
2288 }
2289
2290 /* Check Area ID. */
2291 if (!ospf_check_area_id (oi, ospfh))
2292 {
2293 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2294 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2295 return -1;
2296 }
2297
2298 /* Check network mask, Silently discarded. */
2299 if (! ospf_check_network_mask (oi, iph->ip_src))
2300 {
2301 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2302 IF_NAME (oi), inet_ntoa (iph->ip_src));
2303 return -1;
2304 }
2305
2306 /* Check authentication. */
2307 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2308 {
2309 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2310 IF_NAME (oi));
2311 return -1;
2312 }
2313
2314 if (! ospf_check_auth (oi, ibuf, ospfh))
2315 {
2316 zlog_warn ("interface %s: ospf_read authentication failed.",
2317 IF_NAME (oi));
2318 return -1;
2319 }
2320
2321 /* if check sum is invalid, packet is discarded. */
2322 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2323 {
2324 if (! ospf_check_sum (ospfh))
2325 {
2326 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2327 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2328 return -1;
2329 }
2330 }
2331 else
2332 {
2333 if (ospfh->checksum != 0)
2334 return -1;
2335 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2336 {
2337 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2338 IF_NAME (oi));
2339 return -1;
2340 }
2341 }
2342
2343 return 0;
2344}
2345
2346/* Starting point of packet process function. */
2347int
2348ospf_read (struct thread *thread)
2349{
2350 int ret;
2351 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002352 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002353 struct ospf_interface *oi;
2354 struct ip *iph;
2355 struct ospf_header *ospfh;
2356 u_int16_t length;
2357 struct interface *ifp;
2358
2359 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002360 ospf = THREAD_ARG (thread);
2361 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002362
2363 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002364 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002365 if (ibuf == NULL)
2366 return -1;
2367
paul06f953f2004-10-22 17:00:38 +00002368 iph = (struct ip *) STREAM_DATA (ibuf);
2369 sockopt_iphdrincl_swab_systoh (iph);
2370
paulac191232004-10-22 12:05:17 +00002371 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002372 /* Handle cases where the platform does not support retrieving the ifindex,
2373 and also platforms (such as Solaris 8) that claim to support ifindex
2374 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002375 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002376
pauld3f0d622004-05-05 15:27:15 +00002377 if (ifp == NULL)
2378 {
2379 stream_free (ibuf);
2380 return 0;
2381 }
paul6b333612004-10-11 10:11:25 +00002382
paul718e3742002-12-13 20:15:29 +00002383 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002384 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002385
2386 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002387 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002388 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002389
paul718e3742002-12-13 20:15:29 +00002390 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002391 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002392 {
pauld3241812003-09-29 12:42:39 +00002393 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2394 {
ajs2a42e282004-12-08 18:43:03 +00002395 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002396 inet_ntoa (iph->ip_src));
2397 }
paul718e3742002-12-13 20:15:29 +00002398 stream_free (ibuf);
2399 return 0;
2400 }
2401
2402 /* Adjust size to message length. */
2403 stream_forward (ibuf, iph->ip_hl * 4);
2404
2405 /* Get ospf packet header. */
2406 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2407
2408 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002409 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002410
2411 /* if no local ospf_interface,
2412 * or header area is backbone but ospf_interface is not
2413 * check for VLINK interface
2414 */
2415 if ( (oi == NULL) ||
2416 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2417 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2418 )
2419 {
2420 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2421 {
2422 zlog_warn ("Packet from [%s] received on link %s"
2423 " but no ospf_interface",
2424 inet_ntoa (iph->ip_src), ifp->name);
2425 stream_free (ibuf);
2426 return 0;
2427 }
2428 }
2429
2430 /* else it must be a local ospf interface, check it was received on
2431 * correct link
2432 */
2433 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002434 {
2435 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002436 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002437 stream_free (ibuf);
2438 return 0;
2439 }
ajs847947f2005-02-02 18:38:48 +00002440 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002441 {
ajsba6454e2005-02-08 15:37:30 +00002442 char buf[2][INET_ADDRSTRLEN];
2443 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002444 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002445 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2446 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2447 ifp->name, if_flag_dump(ifp->flags));
ajsc3eab872005-01-29 15:52:07 +00002448 stream_free (ibuf);
ajsba6454e2005-02-08 15:37:30 +00002449 /* Fix multicast memberships? */
2450 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2451 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2452 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2453 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2454 if (oi->multicast_memberships)
2455 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002456 return 0;
2457 }
paul718e3742002-12-13 20:15:29 +00002458
2459 /*
2460 * If the received packet is destined for AllDRouters, the packet
2461 * should be accepted only if the received ospf interface state is
2462 * either DR or Backup -- endo.
2463 */
2464 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2465 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2466 {
ajsba6454e2005-02-08 15:37:30 +00002467 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002468 inet_ntoa (iph->ip_src), IF_NAME (oi),
2469 LOOKUP (ospf_ism_state_msg, oi->state));
2470 stream_free (ibuf);
ajsba6454e2005-02-08 15:37:30 +00002471 /* Try to fix multicast membership. */
2472 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2473 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002474 return 0;
2475 }
2476
2477 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002478 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2479 {
paul718e3742002-12-13 20:15:29 +00002480 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002481 {
ajs2a42e282004-12-08 18:43:03 +00002482 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002483 ospf_packet_dump (ibuf);
2484 }
paul718e3742002-12-13 20:15:29 +00002485
ajs2a42e282004-12-08 18:43:03 +00002486 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002487 ospf_packet_type_str[ospfh->type],
2488 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002489 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2490 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002491
2492 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002493 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002494 }
paul718e3742002-12-13 20:15:29 +00002495
2496 /* Some header verification. */
2497 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2498 if (ret < 0)
2499 {
pauld3241812003-09-29 12:42:39 +00002500 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2501 {
ajs2a42e282004-12-08 18:43:03 +00002502 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002503 "dropping.",
2504 ospf_packet_type_str[ospfh->type],
2505 inet_ntoa (iph->ip_src));
2506 }
paul718e3742002-12-13 20:15:29 +00002507 stream_free (ibuf);
2508 return ret;
2509 }
2510
2511 stream_forward (ibuf, OSPF_HEADER_SIZE);
2512
2513 /* Adjust size to message length. */
2514 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2515
2516 /* Read rest of the packet and call each sort of packet routine. */
2517 switch (ospfh->type)
2518 {
2519 case OSPF_MSG_HELLO:
2520 ospf_hello (iph, ospfh, ibuf, oi, length);
2521 break;
2522 case OSPF_MSG_DB_DESC:
2523 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2524 break;
2525 case OSPF_MSG_LS_REQ:
2526 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2527 break;
2528 case OSPF_MSG_LS_UPD:
2529 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2530 break;
2531 case OSPF_MSG_LS_ACK:
2532 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2533 break;
2534 default:
2535 zlog (NULL, LOG_WARNING,
2536 "interface %s: OSPF packet header type %d is illegal",
2537 IF_NAME (oi), ospfh->type);
2538 break;
2539 }
2540
2541 stream_free (ibuf);
2542 return 0;
2543}
2544
2545/* Make OSPF header. */
2546void
2547ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2548{
2549 struct ospf_header *ospfh;
2550
2551 ospfh = (struct ospf_header *) STREAM_DATA (s);
2552
2553 ospfh->version = (u_char) OSPF_VERSION;
2554 ospfh->type = (u_char) type;
2555
paul68980082003-03-25 05:07:42 +00002556 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002557
2558 ospfh->checksum = 0;
2559 ospfh->area_id = oi->area->area_id;
2560 ospfh->auth_type = htons (ospf_auth_type (oi));
2561
2562 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2563
2564 ospf_output_forward (s, OSPF_HEADER_SIZE);
2565}
2566
2567/* Make Authentication Data. */
2568int
2569ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2570{
2571 struct crypt_key *ck;
2572
2573 switch (ospf_auth_type (oi))
2574 {
2575 case OSPF_AUTH_NULL:
2576 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2577 break;
2578 case OSPF_AUTH_SIMPLE:
2579 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2580 OSPF_AUTH_SIMPLE_SIZE);
2581 break;
2582 case OSPF_AUTH_CRYPTOGRAPHIC:
2583 /* If key is not set, then set 0. */
2584 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2585 {
2586 ospfh->u.crypt.zero = 0;
2587 ospfh->u.crypt.key_id = 0;
2588 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2589 }
2590 else
2591 {
2592 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2593 ospfh->u.crypt.zero = 0;
2594 ospfh->u.crypt.key_id = ck->key_id;
2595 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2596 }
2597 /* note: the seq is done in ospf_make_md5_digest() */
2598 break;
2599 default:
2600 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2601 break;
2602 }
2603
2604 return 0;
2605}
2606
2607/* Fill rest of OSPF header. */
2608void
2609ospf_fill_header (struct ospf_interface *oi,
2610 struct stream *s, u_int16_t length)
2611{
2612 struct ospf_header *ospfh;
2613
2614 ospfh = (struct ospf_header *) STREAM_DATA (s);
2615
2616 /* Fill length. */
2617 ospfh->length = htons (length);
2618
2619 /* Calculate checksum. */
2620 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2621 ospfh->checksum = in_cksum (ospfh, length);
2622 else
2623 ospfh->checksum = 0;
2624
2625 /* Add Authentication Data. */
2626 ospf_make_auth (oi, ospfh);
2627}
2628
2629int
2630ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2631{
2632 struct ospf_neighbor *nbr;
2633 struct route_node *rn;
2634 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2635 struct in_addr mask;
2636 unsigned long p;
2637 int flag = 0;
2638
2639 /* Set netmask of interface. */
2640 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2641 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2642 masklen2ip (oi->address->prefixlen, &mask);
2643 else
2644 memset ((char *) &mask, 0, sizeof (struct in_addr));
2645 stream_put_ipv4 (s, mask.s_addr);
2646
2647 /* Set Hello Interval. */
2648 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2649
2650 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002651 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002652 OPTIONS(oi), IF_NAME (oi));
2653
2654 /* Set Options. */
2655 stream_putc (s, OPTIONS (oi));
2656
2657 /* Set Router Priority. */
2658 stream_putc (s, PRIORITY (oi));
2659
2660 /* Set Router Dead Interval. */
2661 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2662
2663 /* Set Designated Router. */
2664 stream_put_ipv4 (s, DR (oi).s_addr);
2665
paul3a9eb092005-02-08 11:29:41 +00002666 p = stream_get_putp (s);
paul718e3742002-12-13 20:15:29 +00002667
2668 /* Set Backup Designated Router. */
2669 stream_put_ipv4 (s, BDR (oi).s_addr);
2670
2671 /* Add neighbor seen. */
2672 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002673 if ((nbr = rn->info))
2674 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2675 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2676 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2677 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002678 {
2679 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002680 if (nbr->d_router.s_addr != 0
2681 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2682 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2683 flag = 1;
paul718e3742002-12-13 20:15:29 +00002684
2685 stream_put_ipv4 (s, nbr->router_id.s_addr);
2686 length += 4;
2687 }
2688
2689 /* Let neighbor generate BackupSeen. */
2690 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002691 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002692
2693 return length;
2694}
2695
2696int
2697ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2698 struct stream *s)
2699{
2700 struct ospf_lsa *lsa;
2701 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2702 u_char options;
2703 unsigned long pp;
2704 int i;
2705 struct ospf_lsdb *lsdb;
2706
2707 /* Set Interface MTU. */
2708 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2709 stream_putw (s, 0);
2710 else
2711 stream_putw (s, oi->ifp->mtu);
2712
2713 /* Set Options. */
2714 options = OPTIONS (oi);
2715#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002716 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002717 {
2718 if (IS_SET_DD_I (nbr->dd_flags)
2719 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2720 /*
2721 * Set O-bit in the outgoing DD packet for capablity negotiation,
2722 * if one of following case is applicable.
2723 *
2724 * 1) WaitTimer expiration event triggered the neighbor state to
2725 * change to Exstart, but no (valid) DD packet has received
2726 * from the neighbor yet.
2727 *
2728 * 2) At least one DD packet with O-bit on has received from the
2729 * neighbor.
2730 */
2731 SET_FLAG (options, OSPF_OPTION_O);
2732 }
2733#endif /* HAVE_OPAQUE_LSA */
2734 stream_putc (s, options);
2735
2736 /* Keep pointer to flags. */
2737 pp = stream_get_putp (s);
2738 stream_putc (s, nbr->dd_flags);
2739
2740 /* Set DD Sequence Number. */
2741 stream_putl (s, nbr->dd_seqnum);
2742
2743 if (ospf_db_summary_isempty (nbr))
2744 {
2745 if (nbr->state >= NSM_Exchange)
2746 {
2747 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2748 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002749 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002750 }
2751 return length;
2752 }
2753
2754 /* Describe LSA Header from Database Summary List. */
2755 lsdb = &nbr->db_sum;
2756
2757 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2758 {
2759 struct route_table *table = lsdb->type[i].db;
2760 struct route_node *rn;
2761
2762 for (rn = route_top (table); rn; rn = route_next (rn))
2763 if ((lsa = rn->info) != NULL)
2764 {
2765#ifdef HAVE_OPAQUE_LSA
2766 if (IS_OPAQUE_LSA (lsa->data->type)
2767 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2768 {
2769 /* Suppress advertising opaque-informations. */
2770 /* Remove LSA from DB summary list. */
2771 ospf_lsdb_delete (lsdb, lsa);
2772 continue;
2773 }
2774#endif /* HAVE_OPAQUE_LSA */
2775
2776 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2777 {
2778 struct lsa_header *lsah;
2779 u_int16_t ls_age;
2780
2781 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002782 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002783 break;
2784
2785 /* Keep pointer to LS age. */
2786 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2787 stream_get_putp (s));
2788
2789 /* Proceed stream pointer. */
2790 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2791 length += OSPF_LSA_HEADER_SIZE;
2792
2793 /* Set LS age. */
2794 ls_age = LS_AGE (lsa);
2795 lsah->ls_age = htons (ls_age);
2796
2797 }
2798
2799 /* Remove LSA from DB summary list. */
2800 ospf_lsdb_delete (lsdb, lsa);
2801 }
2802 }
2803
2804 return length;
2805}
2806
2807int
2808ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2809 unsigned long delta, struct ospf_neighbor *nbr,
2810 struct ospf_lsa *lsa)
2811{
2812 struct ospf_interface *oi;
2813
2814 oi = nbr->oi;
2815
2816 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002817 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002818 return 0;
2819
2820 stream_putl (s, lsa->data->type);
2821 stream_put_ipv4 (s, lsa->data->id.s_addr);
2822 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2823
2824 ospf_lsa_unlock (nbr->ls_req_last);
2825 nbr->ls_req_last = ospf_lsa_lock (lsa);
2826
2827 *length += 12;
2828 return 1;
2829}
2830
2831int
2832ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2833{
2834 struct ospf_lsa *lsa;
2835 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2836 unsigned long delta = stream_get_putp(s)+12;
2837 struct route_table *table;
2838 struct route_node *rn;
2839 int i;
2840 struct ospf_lsdb *lsdb;
2841
2842 lsdb = &nbr->ls_req;
2843
2844 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2845 {
2846 table = lsdb->type[i].db;
2847 for (rn = route_top (table); rn; rn = route_next (rn))
2848 if ((lsa = (rn->info)) != NULL)
2849 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2850 {
2851 route_unlock_node (rn);
2852 break;
2853 }
2854 }
2855 return length;
2856}
2857
2858int
2859ls_age_increment (struct ospf_lsa *lsa, int delay)
2860{
2861 int age;
2862
2863 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2864
2865 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2866}
2867
2868int
hasso52dc7ee2004-09-23 19:18:23 +00002869ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002870{
2871 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002872 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002873 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002874 unsigned int size_noauth;
paul718e3742002-12-13 20:15:29 +00002875 unsigned long delta = stream_get_putp (s);
2876 unsigned long pp;
2877 int count = 0;
2878
2879 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002880 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002881
paul718e3742002-12-13 20:15:29 +00002882 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002883 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002884
gdt86f1fd92005-01-10 14:20:43 +00002885 /* Calculate amount of packet usable for data. */
2886 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2887
paul718e3742002-12-13 20:15:29 +00002888 while ((node = listhead (update)) != NULL)
2889 {
2890 struct lsa_header *lsah;
2891 u_int16_t ls_age;
2892
2893 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002894 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002895
2896 lsa = getdata (node);
2897 assert (lsa);
2898 assert (lsa->data);
2899
paul68b73392004-09-12 14:21:37 +00002900 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002901 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002902 break;
2903
paul718e3742002-12-13 20:15:29 +00002904 /* Keep pointer to LS age. */
2905 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2906
2907 /* Put LSA to Link State Request. */
2908 stream_put (s, lsa->data, ntohs (lsa->data->length));
2909
2910 /* Set LS age. */
2911 /* each hop must increment an lsa_age by transmit_delay
2912 of OSPF interface */
2913 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2914 lsah->ls_age = htons (ls_age);
2915
2916 length += ntohs (lsa->data->length);
2917 count++;
2918
2919 list_delete_node (update, node);
2920 ospf_lsa_unlock (lsa);
2921 }
2922
2923 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002924 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002925
2926 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002927 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002928 return length;
2929}
2930
2931int
hasso52dc7ee2004-09-23 19:18:23 +00002932ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002933{
hasso52dc7ee2004-09-23 19:18:23 +00002934 struct list *rm_list;
2935 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002936 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2937 unsigned long delta = stream_get_putp(s) + 24;
2938 struct ospf_lsa *lsa;
2939
2940 rm_list = list_new ();
2941
2942 for (node = listhead (ack); node; nextnode (node))
2943 {
2944 lsa = getdata (node);
2945 assert (lsa);
2946
gdt86f1fd92005-01-10 14:20:43 +00002947 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002948 break;
2949
2950 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2951 length += OSPF_LSA_HEADER_SIZE;
2952
2953 listnode_add (rm_list, lsa);
2954 }
2955
2956 /* Remove LSA from LS-Ack list. */
2957 for (node = listhead (rm_list); node; nextnode (node))
2958 {
2959 lsa = (struct ospf_lsa *) getdata (node);
2960
2961 listnode_delete (ack, lsa);
2962 ospf_lsa_unlock (lsa);
2963 }
2964
2965 list_delete (rm_list);
2966
2967 return length;
2968}
2969
2970void
2971ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2972{
2973 struct ospf_packet *op;
2974 u_int16_t length = OSPF_HEADER_SIZE;
2975
2976 op = ospf_packet_new (oi->ifp->mtu);
2977
2978 /* Prepare OSPF common header. */
2979 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2980
2981 /* Prepare OSPF Hello body. */
2982 length += ospf_make_hello (oi, op->s);
2983
2984 /* Fill OSPF header. */
2985 ospf_fill_header (oi, op->s, length);
2986
2987 /* Set packet length. */
2988 op->length = length;
2989
2990 op->dst.s_addr = addr->s_addr;
2991
2992 /* Add packet to the interface output queue. */
2993 ospf_packet_add (oi, op);
2994
2995 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002996 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002997}
2998
2999void
3000ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3001{
3002 struct ospf_interface *oi;
3003
3004 oi = nbr_nbma->oi;
3005 assert(oi);
3006
3007 /* If this is passive interface, do not send OSPF Hello. */
3008 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3009 return;
3010
3011 if (oi->type != OSPF_IFTYPE_NBMA)
3012 return;
3013
3014 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3015 return;
3016
3017 if (PRIORITY(oi) == 0)
3018 return;
3019
3020 if (nbr_nbma->priority == 0
3021 && oi->state != ISM_DR && oi->state != ISM_Backup)
3022 return;
3023
3024 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3025}
3026
3027int
3028ospf_poll_timer (struct thread *thread)
3029{
3030 struct ospf_nbr_nbma *nbr_nbma;
3031
3032 nbr_nbma = THREAD_ARG (thread);
3033 nbr_nbma->t_poll = NULL;
3034
3035 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003036 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003037 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3038
3039 ospf_poll_send (nbr_nbma);
3040
3041 if (nbr_nbma->v_poll > 0)
3042 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3043 nbr_nbma->v_poll);
3044
3045 return 0;
3046}
3047
3048
3049int
3050ospf_hello_reply_timer (struct thread *thread)
3051{
3052 struct ospf_neighbor *nbr;
3053
3054 nbr = THREAD_ARG (thread);
3055 nbr->t_hello_reply = NULL;
3056
3057 assert (nbr->oi);
3058
3059 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003060 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003061 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3062
3063 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3064
3065 return 0;
3066}
3067
3068/* Send OSPF Hello. */
3069void
3070ospf_hello_send (struct ospf_interface *oi)
3071{
3072 struct ospf_packet *op;
3073 u_int16_t length = OSPF_HEADER_SIZE;
3074
3075 /* If this is passive interface, do not send OSPF Hello. */
3076 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3077 return;
3078
3079 op = ospf_packet_new (oi->ifp->mtu);
3080
3081 /* Prepare OSPF common header. */
3082 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3083
3084 /* Prepare OSPF Hello body. */
3085 length += ospf_make_hello (oi, op->s);
3086
3087 /* Fill OSPF header. */
3088 ospf_fill_header (oi, op->s, length);
3089
3090 /* Set packet length. */
3091 op->length = length;
3092
3093 if (oi->type == OSPF_IFTYPE_NBMA)
3094 {
3095 struct ospf_neighbor *nbr;
3096 struct route_node *rn;
3097
3098 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3099 if ((nbr = rn->info))
3100 if (nbr != oi->nbr_self)
3101 if (nbr->state != NSM_Down)
3102 {
3103 /* RFC 2328 Section 9.5.1
3104 If the router is not eligible to become Designated Router,
3105 it must periodically send Hello Packets to both the
3106 Designated Router and the Backup Designated Router (if they
3107 exist). */
3108 if (PRIORITY(oi) == 0 &&
3109 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3110 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3111 continue;
3112
3113 /* If the router is eligible to become Designated Router, it
3114 must periodically send Hello Packets to all neighbors that
3115 are also eligible. In addition, if the router is itself the
3116 Designated Router or Backup Designated Router, it must also
3117 send periodic Hello Packets to all other neighbors. */
3118
3119 if (nbr->priority == 0 && oi->state == ISM_DROther)
3120 continue;
3121 /* if oi->state == Waiting, send hello to all neighbors */
3122 {
3123 struct ospf_packet *op_dup;
3124
3125 op_dup = ospf_packet_dup(op);
3126 op_dup->dst = nbr->address.u.prefix4;
3127
3128 /* Add packet to the interface output queue. */
3129 ospf_packet_add (oi, op_dup);
3130
paul020709f2003-04-04 02:44:16 +00003131 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003132 }
3133
3134 }
3135 ospf_packet_free (op);
3136 }
3137 else
3138 {
3139 /* Decide destination address. */
3140 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3141 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3142 else
3143 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3144
3145 /* Add packet to the interface output queue. */
3146 ospf_packet_add (oi, op);
3147
3148 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003149 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003150 }
3151}
3152
3153/* Send OSPF Database Description. */
3154void
3155ospf_db_desc_send (struct ospf_neighbor *nbr)
3156{
3157 struct ospf_interface *oi;
3158 struct ospf_packet *op;
3159 u_int16_t length = OSPF_HEADER_SIZE;
3160
3161 oi = nbr->oi;
3162 op = ospf_packet_new (oi->ifp->mtu);
3163
3164 /* Prepare OSPF common header. */
3165 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3166
3167 /* Prepare OSPF Database Description body. */
3168 length += ospf_make_db_desc (oi, nbr, op->s);
3169
3170 /* Fill OSPF header. */
3171 ospf_fill_header (oi, op->s, length);
3172
3173 /* Set packet length. */
3174 op->length = length;
3175
3176 /* Decide destination address. */
3177 op->dst = nbr->address.u.prefix4;
3178
3179 /* Add packet to the interface output queue. */
3180 ospf_packet_add (oi, op);
3181
3182 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003183 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003184
3185 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3186 if (nbr->last_send)
3187 ospf_packet_free (nbr->last_send);
3188 nbr->last_send = ospf_packet_dup (op);
3189 gettimeofday (&nbr->last_send_ts, NULL);
3190}
3191
3192/* Re-send Database Description. */
3193void
3194ospf_db_desc_resend (struct ospf_neighbor *nbr)
3195{
3196 struct ospf_interface *oi;
3197
3198 oi = nbr->oi;
3199
3200 /* Add packet to the interface output queue. */
3201 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3202
3203 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003204 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003205}
3206
3207/* Send Link State Request. */
3208void
3209ospf_ls_req_send (struct ospf_neighbor *nbr)
3210{
3211 struct ospf_interface *oi;
3212 struct ospf_packet *op;
3213 u_int16_t length = OSPF_HEADER_SIZE;
3214
3215 oi = nbr->oi;
3216 op = ospf_packet_new (oi->ifp->mtu);
3217
3218 /* Prepare OSPF common header. */
3219 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3220
3221 /* Prepare OSPF Link State Request body. */
3222 length += ospf_make_ls_req (nbr, op->s);
3223 if (length == OSPF_HEADER_SIZE)
3224 {
3225 ospf_packet_free (op);
3226 return;
3227 }
3228
3229 /* Fill OSPF header. */
3230 ospf_fill_header (oi, op->s, length);
3231
3232 /* Set packet length. */
3233 op->length = length;
3234
3235 /* Decide destination address. */
3236 op->dst = nbr->address.u.prefix4;
3237
3238 /* Add packet to the interface output queue. */
3239 ospf_packet_add (oi, op);
3240
3241 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003242 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003243
3244 /* Add Link State Request Retransmission Timer. */
3245 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3246}
3247
3248/* Send Link State Update with an LSA. */
3249void
3250ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3251 int flag)
3252{
hasso52dc7ee2004-09-23 19:18:23 +00003253 struct list *update;
paul718e3742002-12-13 20:15:29 +00003254
3255 update = list_new ();
3256
3257 listnode_add (update, lsa);
3258 ospf_ls_upd_send (nbr, update, flag);
3259
3260 list_delete (update);
3261}
3262
paul68b73392004-09-12 14:21:37 +00003263/* Determine size for packet. Must be at least big enough to accomodate next
3264 * LSA on list, which may be bigger than MTU size.
3265 *
3266 * Return pointer to new ospf_packet
3267 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3268 * on packet sizes (in which case offending LSA is deleted from update list)
3269 */
3270static struct ospf_packet *
3271ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3272{
3273 struct ospf_lsa *lsa;
3274 struct listnode *ln;
3275 size_t size;
3276 static char warned = 0;
3277
3278 ln = listhead (update);
3279 lsa = getdata (ln);
3280 assert (lsa);
3281 assert (lsa->data);
3282
3283 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3284 > ospf_packet_max (oi))
3285 {
3286 if (!warned)
3287 {
3288 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3289 "will need to fragment. Not optimal. Try divide up"
3290 " your network with areas. Use 'debug ospf packet send'"
3291 " to see details, or look at 'show ip ospf database ..'");
3292 warned = 1;
3293 }
3294
3295 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003296 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003297 " %d bytes originated by %s, will be fragmented!",
3298 inet_ntoa (lsa->data->id),
3299 ntohs (lsa->data->length),
3300 inet_ntoa (lsa->data->adv_router));
3301
3302 /*
3303 * Allocate just enough to fit this LSA only, to avoid including other
3304 * LSAs in fragmented LSA Updates.
3305 */
3306 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3307 + OSPF_LS_UPD_MIN_SIZE;
3308 }
3309 else
3310 size = oi->ifp->mtu;
3311
gdt86f1fd92005-01-10 14:20:43 +00003312 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003313 if (size > OSPF_MAX_PACKET_SIZE)
3314 {
3315 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003316 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003317 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003318 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003319 (long int) size);
paul68b73392004-09-12 14:21:37 +00003320 list_delete_node (update, ln);
3321 return NULL;
3322 }
3323
3324 return ospf_packet_new (size);
3325}
3326
paul718e3742002-12-13 20:15:29 +00003327static void
hasso52dc7ee2004-09-23 19:18:23 +00003328ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003329 struct in_addr addr)
3330{
3331 struct ospf_packet *op;
3332 u_int16_t length = OSPF_HEADER_SIZE;
3333
3334 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003335 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003336
3337 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003338
3339 /* Prepare OSPF common header. */
3340 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3341
paul59ea14c2004-07-14 20:50:36 +00003342 /* Prepare OSPF Link State Update body.
3343 * Includes Type-7 translation.
3344 */
paul718e3742002-12-13 20:15:29 +00003345 length += ospf_make_ls_upd (oi, update, op->s);
3346
3347 /* Fill OSPF header. */
3348 ospf_fill_header (oi, op->s, length);
3349
3350 /* Set packet length. */
3351 op->length = length;
3352
3353 /* Decide destination address. */
3354 op->dst.s_addr = addr.s_addr;
3355
3356 /* Add packet to the interface output queue. */
3357 ospf_packet_add (oi, op);
3358
3359 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003360 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003361}
3362
3363static int
3364ospf_ls_upd_send_queue_event (struct thread *thread)
3365{
3366 struct ospf_interface *oi = THREAD_ARG(thread);
3367 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003368 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003369 struct list *update;
paul68b73392004-09-12 14:21:37 +00003370 char again = 0;
paul718e3742002-12-13 20:15:29 +00003371
3372 oi->t_ls_upd_event = NULL;
3373
3374 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003375 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003376
paul736d3442003-07-24 23:22:57 +00003377 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003378 {
paul736d3442003-07-24 23:22:57 +00003379 rnext = route_next (rn);
3380
paul718e3742002-12-13 20:15:29 +00003381 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003382 continue;
paul68b73392004-09-12 14:21:37 +00003383
3384 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003385
paul48fe13b2004-07-27 17:40:44 +00003386 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003387
paul68b73392004-09-12 14:21:37 +00003388 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003389 if (listcount(update) == 0)
3390 {
3391 list_delete (rn->info);
3392 rn->info = NULL;
3393 route_unlock_node (rn);
3394 }
3395 else
paul68b73392004-09-12 14:21:37 +00003396 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003397 }
3398
3399 if (again != 0)
3400 {
3401 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003402 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003403 " %d nodes to try again, raising new event", again);
3404 oi->t_ls_upd_event =
3405 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003406 }
3407
3408 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003409 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003410
paul718e3742002-12-13 20:15:29 +00003411 return 0;
3412}
3413
3414void
hasso52dc7ee2004-09-23 19:18:23 +00003415ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003416{
3417 struct ospf_interface *oi;
3418 struct prefix_ipv4 p;
3419 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003420 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003421
3422 oi = nbr->oi;
3423
3424 p.family = AF_INET;
3425 p.prefixlen = IPV4_MAX_BITLEN;
3426
3427 /* Decide destination address. */
3428 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3429 p.prefix = oi->vl_data->peer_addr;
3430 else if (flag == OSPF_SEND_PACKET_DIRECT)
3431 p.prefix = nbr->address.u.prefix4;
3432 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3433 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3434 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3435 && (flag == OSPF_SEND_PACKET_INDIRECT))
3436 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003437 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3438 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003439 else
3440 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3441
3442 if (oi->type == OSPF_IFTYPE_NBMA)
3443 {
3444 if (flag == OSPF_SEND_PACKET_INDIRECT)
3445 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3446 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3447 zlog_warn ("* LS-Update is sent to myself.");
3448 }
3449
3450 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3451
3452 if (rn->info == NULL)
3453 rn->info = list_new ();
3454
3455 for (n = listhead (update); n; nextnode (n))
3456 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3457
3458 if (oi->t_ls_upd_event == NULL)
3459 oi->t_ls_upd_event =
3460 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3461}
3462
3463static void
hasso52dc7ee2004-09-23 19:18:23 +00003464ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3465 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003466{
3467 struct ospf_packet *op;
3468 u_int16_t length = OSPF_HEADER_SIZE;
3469
3470 op = ospf_packet_new (oi->ifp->mtu);
3471
3472 /* Prepare OSPF common header. */
3473 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3474
3475 /* Prepare OSPF Link State Acknowledgment body. */
3476 length += ospf_make_ls_ack (oi, ack, op->s);
3477
3478 /* Fill OSPF header. */
3479 ospf_fill_header (oi, op->s, length);
3480
3481 /* Set packet length. */
3482 op->length = length;
3483
3484 /* Set destination IP address. */
3485 op->dst = dst;
3486
3487 /* Add packet to the interface output queue. */
3488 ospf_packet_add (oi, op);
3489
3490 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003491 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003492}
3493
3494static int
3495ospf_ls_ack_send_event (struct thread *thread)
3496{
3497 struct ospf_interface *oi = THREAD_ARG (thread);
3498
3499 oi->t_ls_ack_direct = NULL;
3500
3501 while (listcount (oi->ls_ack_direct.ls_ack))
3502 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3503 oi->ls_ack_direct.dst);
3504
3505 return 0;
3506}
3507
3508void
3509ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3510{
3511 struct ospf_interface *oi = nbr->oi;
3512
3513 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3514 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3515
3516 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3517
3518 if (oi->t_ls_ack_direct == NULL)
3519 oi->t_ls_ack_direct =
3520 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3521}
3522
3523/* Send Link State Acknowledgment delayed. */
3524void
3525ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3526{
3527 struct in_addr dst;
3528
3529 /* Decide destination address. */
3530 /* RFC2328 Section 13.5 On non-broadcast
3531 networks, delayed Link State Acknowledgment packets must be
3532 unicast separately over each adjacency (i.e., neighbor whose
3533 state is >= Exchange). */
3534 if (oi->type == OSPF_IFTYPE_NBMA)
3535 {
3536 struct ospf_neighbor *nbr;
3537 struct route_node *rn;
3538
3539 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3540 if ((nbr = rn->info) != NULL)
3541 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3542 while (listcount (oi->ls_ack))
3543 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3544 return;
3545 }
3546 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3547 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3548 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3549 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3550 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3551 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003552 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3553 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003554 else
3555 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3556
3557 while (listcount (oi->ls_ack))
3558 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3559}