blob: 87913361cf3443342ce7b09451e048aef0791648 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Sending and Receiving OSPF Packets.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "memory.h"
27#include "linklist.h"
28#include "prefix.h"
29#include "if.h"
30#include "table.h"
31#include "sockunion.h"
32#include "stream.h"
33#include "log.h"
paul2dd8bb42004-07-23 15:13:48 +000034#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000035#include "md5-gnu.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_flood.h"
49#include "ospfd/ospf_dump.h"
50
hasso52dc7ee2004-09-23 19:18:23 +000051static void ospf_ls_ack_send_list (struct ospf_interface *, struct list *,
paul718e3742002-12-13 20:15:29 +000052 struct in_addr);
53
54/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000055const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000056{
57 "unknown",
58 "Hello",
59 "Database Description",
60 "Link State Request",
61 "Link State Update",
62 "Link State Acknowledgment",
63};
64
65extern int in_cksum (void *ptr, int nbytes);
66
67/* OSPF authentication checking function */
68int
69ospf_auth_type (struct ospf_interface *oi)
70{
71 int auth_type;
72
73 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
74 auth_type = oi->area->auth_type;
75 else
76 auth_type = OSPF_IF_PARAM (oi, auth_type);
77
78 /* Handle case where MD5 key list is not configured aka Cisco */
79 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
80 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
81 return OSPF_AUTH_NULL;
82
83 return auth_type;
84
85}
86
paul718e3742002-12-13 20:15:29 +000087struct ospf_packet *
88ospf_packet_new (size_t size)
89{
90 struct ospf_packet *new;
91
92 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
93 new->s = stream_new (size);
94
95 return new;
96}
97
98void
99ospf_packet_free (struct ospf_packet *op)
100{
101 if (op->s)
102 stream_free (op->s);
103
104 XFREE (MTYPE_OSPF_PACKET, op);
105
106 op = NULL;
107}
108
109struct ospf_fifo *
110ospf_fifo_new ()
111{
112 struct ospf_fifo *new;
113
114 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
115 return new;
116}
117
118/* Add new packet to fifo. */
119void
120ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
121{
122 if (fifo->tail)
123 fifo->tail->next = op;
124 else
125 fifo->head = op;
126
127 fifo->tail = op;
128
129 fifo->count++;
130}
131
132/* Delete first packet from fifo. */
133struct ospf_packet *
134ospf_fifo_pop (struct ospf_fifo *fifo)
135{
136 struct ospf_packet *op;
137
138 op = fifo->head;
139
140 if (op)
141 {
142 fifo->head = op->next;
143
144 if (fifo->head == NULL)
145 fifo->tail = NULL;
146
147 fifo->count--;
148 }
149
150 return op;
151}
152
153/* Return first fifo entry. */
154struct ospf_packet *
155ospf_fifo_head (struct ospf_fifo *fifo)
156{
157 return fifo->head;
158}
159
160/* Flush ospf packet fifo. */
161void
162ospf_fifo_flush (struct ospf_fifo *fifo)
163{
164 struct ospf_packet *op;
165 struct ospf_packet *next;
166
167 for (op = fifo->head; op; op = next)
168 {
169 next = op->next;
170 ospf_packet_free (op);
171 }
172 fifo->head = fifo->tail = NULL;
173 fifo->count = 0;
174}
175
176/* Free ospf packet fifo. */
177void
178ospf_fifo_free (struct ospf_fifo *fifo)
179{
180 ospf_fifo_flush (fifo);
181
182 XFREE (MTYPE_OSPF_FIFO, fifo);
183}
184
185void
186ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
187{
ajsc3eab872005-01-29 15:52:07 +0000188 if (!oi->obuf)
189 {
190 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
191 "destination %s) called with NULL obuf, ignoring "
192 "(please report this bug)!\n",
193 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
194 ospf_packet_type_str[stream_getc_from(op->s, 1)],
195 inet_ntoa (op->dst));
196 return;
197 }
198
paul718e3742002-12-13 20:15:29 +0000199 /* Add packet to end of queue. */
200 ospf_fifo_push (oi->obuf, op);
201
202 /* Debug of packet fifo*/
203 /* ospf_fifo_debug (oi->obuf); */
204}
205
206void
207ospf_packet_delete (struct ospf_interface *oi)
208{
209 struct ospf_packet *op;
210
211 op = ospf_fifo_pop (oi->obuf);
212
213 if (op)
214 ospf_packet_free (op);
215}
216
paul718e3742002-12-13 20:15:29 +0000217struct ospf_packet *
218ospf_packet_dup (struct ospf_packet *op)
219{
220 struct ospf_packet *new;
221
paul37163d62003-02-03 18:40:56 +0000222 if (stream_get_endp(op->s) != op->length)
223 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000224 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000225
226 /* Reserve space for MD5 authentication that may be added later. */
227 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000228 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000229
230 new->dst = op->dst;
231 new->length = op->length;
232
233 return new;
234}
235
gdt86f1fd92005-01-10 14:20:43 +0000236/* XXX inline */
237unsigned int
238ospf_packet_authspace (struct ospf_interface *oi)
239{
240 int auth = 0;
241
242 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
243 auth = OSPF_AUTH_MD5_SIZE;
244
245 return auth;
246}
247
paul6c835672004-10-11 11:00:30 +0000248unsigned int
paul718e3742002-12-13 20:15:29 +0000249ospf_packet_max (struct ospf_interface *oi)
250{
251 int max;
252
gdt86f1fd92005-01-10 14:20:43 +0000253 max = oi->ifp->mtu - ospf_packet_authspace(oi);
254
paul68b73392004-09-12 14:21:37 +0000255 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000256
257 return max;
258}
259
260
261int
262ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
263 u_int16_t length)
264{
paul6c835672004-10-11 11:00:30 +0000265 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000266 struct md5_ctx ctx;
267 unsigned char digest[OSPF_AUTH_MD5_SIZE];
268 unsigned char *pdigest;
269 struct crypt_key *ck;
270 struct ospf_header *ospfh;
271 struct ospf_neighbor *nbr;
272
273
274 ibuf = STREAM_PNT (s);
275 ospfh = (struct ospf_header *) ibuf;
276
277 /* Get pointer to the end of the packet. */
278 pdigest = ibuf + length;
279
280 /* Get secret key. */
281 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
282 ospfh->u.crypt.key_id);
283 if (ck == NULL)
284 {
285 zlog_warn ("interface %s: ospf_check_md5 no key %d",
286 IF_NAME (oi), ospfh->u.crypt.key_id);
287 return 0;
288 }
289
290 /* check crypto seqnum. */
291 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
292
293 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
294 {
295 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
296 IF_NAME (oi),
297 ntohl(ospfh->u.crypt.crypt_seqnum),
298 ntohl(nbr->crypt_seqnum));
299 return 0;
300 }
301
302 /* Generate a digest for the ospf packet - their digest + our digest. */
303 md5_init_ctx (&ctx);
304 md5_process_bytes (ibuf, length, &ctx);
305 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
306 md5_finish_ctx (&ctx, digest);
307
308 /* compare the two */
309 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
310 {
311 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
312 IF_NAME (oi));
313 return 0;
314 }
315
316 /* save neighbor's crypt_seqnum */
317 if (nbr)
318 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
319 return 1;
320}
321
322/* This function is called from ospf_write(), it will detect the
323 authentication scheme and if it is MD5, it will change the sequence
324 and update the MD5 digest. */
325int
326ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
327{
328 struct ospf_header *ospfh;
329 unsigned char digest[OSPF_AUTH_MD5_SIZE];
330 struct md5_ctx ctx;
331 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000332 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000333 struct crypt_key *ck;
334 char *auth_key;
335
336 ibuf = STREAM_DATA (op->s);
337 ospfh = (struct ospf_header *) ibuf;
338
339 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
340 return 0;
341
342 /* We do this here so when we dup a packet, we don't have to
343 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000344 t = (time(NULL) & 0xFFFFFFFF);
345 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
346 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000347
348 /* Get MD5 Authentication key from auth_key list. */
349 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000350 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000351 else
352 {
353 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000354 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000355 }
356
357 /* Generate a digest for the entire packet + our secret key. */
358 md5_init_ctx (&ctx);
359 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
360 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
361 md5_finish_ctx (&ctx, digest);
362
363 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000364 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000365
366 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000367 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
368
paul37163d62003-02-03 18:40:56 +0000369 if (stream_get_endp(op->s) != op->length)
370 zlog_warn("ospf_make_md5_digest: length mismatch stream %ld ospf_packet %d", stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000371
372 return OSPF_AUTH_MD5_SIZE;
373}
374
375
376int
377ospf_ls_req_timer (struct thread *thread)
378{
379 struct ospf_neighbor *nbr;
380
381 nbr = THREAD_ARG (thread);
382 nbr->t_ls_req = NULL;
383
384 /* Send Link State Request. */
385 if (ospf_ls_request_count (nbr))
386 ospf_ls_req_send (nbr);
387
388 /* Set Link State Request retransmission timer. */
389 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
390
391 return 0;
392}
393
394void
395ospf_ls_req_event (struct ospf_neighbor *nbr)
396{
397 if (nbr->t_ls_req)
398 {
399 thread_cancel (nbr->t_ls_req);
400 nbr->t_ls_req = NULL;
401 }
402 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
403}
404
405/* Cyclic timer function. Fist registered in ospf_nbr_new () in
406 ospf_neighbor.c */
407int
408ospf_ls_upd_timer (struct thread *thread)
409{
410 struct ospf_neighbor *nbr;
411
412 nbr = THREAD_ARG (thread);
413 nbr->t_ls_upd = NULL;
414
415 /* Send Link State Update. */
416 if (ospf_ls_retransmit_count (nbr) > 0)
417 {
hasso52dc7ee2004-09-23 19:18:23 +0000418 struct list *update;
paul718e3742002-12-13 20:15:29 +0000419 struct ospf_lsdb *lsdb;
420 int i;
421 struct timeval now;
422 int retransmit_interval;
423
424 gettimeofday (&now, NULL);
425 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
426
427 lsdb = &nbr->ls_rxmt;
428 update = list_new ();
429
430 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
431 {
432 struct route_table *table = lsdb->type[i].db;
433 struct route_node *rn;
434
435 for (rn = route_top (table); rn; rn = route_next (rn))
436 {
437 struct ospf_lsa *lsa;
438
439 if ((lsa = rn->info) != NULL)
440 /* Don't retransmit an LSA if we received it within
441 the last RxmtInterval seconds - this is to allow the
442 neighbour a chance to acknowledge the LSA as it may
443 have ben just received before the retransmit timer
444 fired. This is a small tweak to what is in the RFC,
445 but it will cut out out a lot of retransmit traffic
446 - MAG */
447 if (tv_cmp (tv_sub (now, lsa->tv_recv),
448 int2tv (retransmit_interval)) >= 0)
449 listnode_add (update, rn->info);
450 }
451 }
452
453 if (listcount (update) > 0)
454 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
455 list_delete (update);
456 }
457
458 /* Set LS Update retransmission timer. */
459 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
460
461 return 0;
462}
463
464int
465ospf_ls_ack_timer (struct thread *thread)
466{
467 struct ospf_interface *oi;
468
469 oi = THREAD_ARG (thread);
470 oi->t_ls_ack = NULL;
471
472 /* Send Link State Acknowledgment. */
473 if (listcount (oi->ls_ack) > 0)
474 ospf_ls_ack_send_delayed (oi);
475
476 /* Set LS Ack timer. */
477 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
478
479 return 0;
480}
481
paul0bfeca32004-09-24 08:07:54 +0000482#ifdef WANT_OSPF_WRITE_FRAGMENT
483void
paul6a99f832004-09-27 12:56:30 +0000484ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000485 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000486 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000487{
488#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000489 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000490 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000491 int ret;
paul0bfeca32004-09-24 08:07:54 +0000492
493 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000494 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000495
496 /* we can but try.
497 *
498 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
499 * well as the IP_MF flag, making this all quite pointless.
500 *
501 * However, for a system on which IP_MF is left alone, and ip_id left
502 * alone or else which sets same ip_id for each fragment this might
503 * work, eg linux.
504 *
505 * XXX-TODO: It would be much nicer to have the kernel's use their
506 * existing fragmentation support to do this for us. Bugs/RFEs need to
507 * be raised against the various kernels.
508 */
509
510 /* set More Frag */
511 iph->ip_off |= IP_MF;
512
513 /* ip frag offset is expressed in units of 8byte words */
514 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
515
paul62d8e962004-11-02 20:26:45 +0000516 iovp = &msg->msg_iov[1];
517
paul0bfeca32004-09-24 08:07:54 +0000518 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
519 > maxdatasize )
520 {
521 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000522 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
523 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000524 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000525
paul18b12c32004-10-05 14:38:29 +0000526 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000527
paul6a99f832004-09-27 12:56:30 +0000528 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000529
paul18b12c32004-10-05 14:38:29 +0000530 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000531
532 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000533 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000534 " id %d, off %d, len %d failed with %s",
535 inet_ntoa (iph->ip_dst),
536 iph->ip_id,
537 iph->ip_off,
538 iph->ip_len,
ajs6099b3b2004-11-20 02:06:59 +0000539 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000540
paul37ccfa32004-10-31 11:24:51 +0000541 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
542 {
ajs2a42e282004-12-08 18:43:03 +0000543 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000544 iph->ip_id, iph->ip_off, iph->ip_len,
545 inet_ntoa (iph->ip_dst));
546 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
547 {
ajs2a42e282004-12-08 18:43:03 +0000548 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000549 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000550 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000551 }
552 }
553
paul0bfeca32004-09-24 08:07:54 +0000554 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000555 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000556 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000557 }
558
559 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000560 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
561 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000562 iph->ip_off &= (~IP_MF);
563}
564#endif /* WANT_OSPF_WRITE_FRAGMENT */
565
paul718e3742002-12-13 20:15:29 +0000566int
567ospf_write (struct thread *thread)
568{
paul68980082003-03-25 05:07:42 +0000569 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000570 struct ospf_interface *oi;
571 struct ospf_packet *op;
572 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000573 struct ip iph;
574 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000575 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000576 u_char type;
577 int ret;
578 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000579 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000580#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000581 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000582#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000583 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000584#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000585
paul68980082003-03-25 05:07:42 +0000586 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000587
paul68980082003-03-25 05:07:42 +0000588 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000589 assert (node);
590 oi = getdata (node);
591 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000592
593#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000594 /* seed ipid static with low order bits of time */
595 if (ipid == 0)
596 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000597#endif /* WANT_OSPF_WRITE_FRAGMENT */
598
paul68b73392004-09-12 14:21:37 +0000599 /* convenience - max OSPF data per packet */
600 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
601
paul718e3742002-12-13 20:15:29 +0000602 /* Get one packet from queue. */
603 op = ospf_fifo_head (oi->obuf);
604 assert (op);
605 assert (op->length >= OSPF_HEADER_SIZE);
606
paul68980082003-03-25 05:07:42 +0000607 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
608 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000609 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
610
paul718e3742002-12-13 20:15:29 +0000611 /* Rewrite the md5 signature & update the seq */
612 ospf_make_md5_digest (oi, op);
613
paul37ccfa32004-10-31 11:24:51 +0000614 /* Retrieve OSPF packet type. */
615 stream_set_getp (op->s, 1);
616 type = stream_getc (op->s);
617
paul68b73392004-09-12 14:21:37 +0000618 /* reset get pointer */
619 stream_set_getp (op->s, 0);
620
621 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000622 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000623
paul718e3742002-12-13 20:15:29 +0000624 sa_dst.sin_family = AF_INET;
625#ifdef HAVE_SIN_LEN
626 sa_dst.sin_len = sizeof(sa_dst);
627#endif /* HAVE_SIN_LEN */
628 sa_dst.sin_addr = op->dst;
629 sa_dst.sin_port = htons (0);
630
631 /* Set DONTROUTE flag if dst is unicast. */
632 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
633 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
634 flags = MSG_DONTROUTE;
635
paul68b73392004-09-12 14:21:37 +0000636 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
637 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000638 if ( sizeof (struct ip)
639 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000640 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
641
paul718e3742002-12-13 20:15:29 +0000642 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000643 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000644 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000645
paul0bfeca32004-09-24 08:07:54 +0000646#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000647 /* XXX-MT: not thread-safe at all..
648 * XXX: this presumes this is only programme sending OSPF packets
649 * otherwise, no guarantee ipid will be unique
650 */
651 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000652#endif /* WANT_OSPF_WRITE_FRAGMENT */
653
paul718e3742002-12-13 20:15:29 +0000654 iph.ip_off = 0;
655 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
656 iph.ip_ttl = OSPF_VL_IP_TTL;
657 else
658 iph.ip_ttl = OSPF_IP_TTL;
659 iph.ip_p = IPPROTO_OSPFIGP;
660 iph.ip_sum = 0;
661 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
662 iph.ip_dst.s_addr = op->dst.s_addr;
663
664 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000665 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000666 msg.msg_namelen = sizeof (sa_dst);
667 msg.msg_iov = iov;
668 msg.msg_iovlen = 2;
669 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000670 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
671 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000672 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000673
674 /* Sadly we can not rely on kernels to fragment packets because of either
675 * IP_HDRINCL and/or multicast destination being set.
676 */
paul0bfeca32004-09-24 08:07:54 +0000677#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000678 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000679 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
680 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000681#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000682
683 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000684 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000685 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000686 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000687
688 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000689 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
690 "id %d, off %d, len %d: %s",
691 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
692 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000693
paul718e3742002-12-13 20:15:29 +0000694 /* Show debug sending packet. */
695 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
696 {
697 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
698 {
ajs2a42e282004-12-08 18:43:03 +0000699 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000700 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000701 stream_set_getp (op->s, 0);
702 ospf_packet_dump (op->s);
703 }
704
ajs2a42e282004-12-08 18:43:03 +0000705 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000706 ospf_packet_type_str[type], inet_ntoa (op->dst),
707 IF_NAME (oi));
708
709 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000710 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000711 }
712
713 /* Now delete packet from queue. */
714 ospf_packet_delete (oi);
715
716 if (ospf_fifo_head (oi->obuf) == NULL)
717 {
718 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000719 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000720 }
721
722 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000723 if (!list_isempty (ospf->oi_write_q))
724 ospf->t_write =
725 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000726
727 return 0;
728}
729
730/* OSPF Hello message read -- RFC2328 Section 10.5. */
731void
732ospf_hello (struct ip *iph, struct ospf_header *ospfh,
733 struct stream * s, struct ospf_interface *oi, int size)
734{
735 struct ospf_hello *hello;
736 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000737 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000738 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000739
740 /* increment statistics. */
741 oi->hello_in++;
742
743 hello = (struct ospf_hello *) STREAM_PNT (s);
744
745 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000746 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000747 {
748 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
749 {
ajs2a42e282004-12-08 18:43:03 +0000750 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000751 "dropping.",
752 ospf_packet_type_str[ospfh->type],
753 inet_ntoa (iph->ip_src));
754 }
755 return;
756 }
paul718e3742002-12-13 20:15:29 +0000757
758 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000759 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000760 char buf[3][INET_ADDRSTRLEN];
761 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
762 "should not receive hellos on passive interface %s!",
763 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
764 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
765 inet_ntop(AF_INET, &oi->address->u.prefix4,
766 buf[2], sizeof(buf[2])));
767 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
768 {
769 /* Try to fix multicast membership. */
770 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
771 ospf_if_set_multicast(oi);
772 }
paul718e3742002-12-13 20:15:29 +0000773 return;
paulf2c80652002-12-13 21:44:27 +0000774 }
paul718e3742002-12-13 20:15:29 +0000775
776 /* get neighbor prefix. */
777 p.family = AF_INET;
778 p.prefixlen = ip_masklen (hello->network_mask);
779 p.u.prefix4 = iph->ip_src;
780
781 /* Compare network mask. */
782 /* Checking is ignored for Point-to-Point and Virtual link. */
783 if (oi->type != OSPF_IFTYPE_POINTOPOINT
784 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
785 if (oi->address->prefixlen != p.prefixlen)
786 {
787 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
788 inet_ntoa (ospfh->router_id));
789 return;
790 }
791
792 /* Compare Hello Interval. */
793 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
794 {
795 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
796 inet_ntoa (ospfh->router_id));
797 return;
798 }
799
800 /* Compare Router Dead Interval. */
801 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
802 {
803 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
804 inet_ntoa (ospfh->router_id));
805 return;
806 }
807
808 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000809 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000810 inet_ntoa (ospfh->router_id),
811 ospf_options_dump (hello->options));
812
813 /* Compare options. */
814#define REJECT_IF_TBIT_ON 1 /* XXX */
815#ifdef REJECT_IF_TBIT_ON
816 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
817 {
818 /*
819 * This router does not support non-zero TOS.
820 * Drop this Hello packet not to establish neighbor relationship.
821 */
822 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
823 inet_ntoa (ospfh->router_id));
824 return;
825 }
826#endif /* REJECT_IF_TBIT_ON */
827
828#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000829 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000830 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
831 {
832 /*
833 * This router does know the correct usage of O-bit
834 * the bit should be set in DD packet only.
835 */
836 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
837 inet_ntoa (ospfh->router_id));
838#ifdef STRICT_OBIT_USAGE_CHECK
839 return; /* Reject this packet. */
840#else /* STRICT_OBIT_USAGE_CHECK */
841 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
842#endif /* STRICT_OBIT_USAGE_CHECK */
843 }
844#endif /* HAVE_OPAQUE_LSA */
845
846 /* new for NSSA is to ensure that NP is on and E is off */
847
paul718e3742002-12-13 20:15:29 +0000848 if (oi->area->external_routing == OSPF_AREA_NSSA)
849 {
850 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
851 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
852 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
853 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
854 {
855 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
856 return;
857 }
858 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000859 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000860 }
861 else
paul718e3742002-12-13 20:15:29 +0000862 /* The setting of the E-bit found in the Hello Packet's Options
863 field must match this area's ExternalRoutingCapability A
864 mismatch causes processing to stop and the packet to be
865 dropped. The setting of the rest of the bits in the Hello
866 Packet's Options field should be ignored. */
867 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
868 CHECK_FLAG (hello->options, OSPF_OPTION_E))
869 {
ajs3aa8d5f2004-12-11 18:00:06 +0000870 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
871 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000872 return;
873 }
paul718e3742002-12-13 20:15:29 +0000874
pauld3f0d622004-05-05 15:27:15 +0000875 /* get neighbour struct */
876 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
877
878 /* neighbour must be valid, ospf_nbr_get creates if none existed */
879 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000880
881 old_state = nbr->state;
882
883 /* Add event to thread. */
884 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
885
886 /* RFC2328 Section 9.5.1
887 If the router is not eligible to become Designated Router,
888 (snip) It must also send an Hello Packet in reply to an
889 Hello Packet received from any eligible neighbor (other than
890 the current Designated Router and Backup Designated Router). */
891 if (oi->type == OSPF_IFTYPE_NBMA)
892 if (PRIORITY(oi) == 0 && hello->priority > 0
893 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
894 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
895 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
896 OSPF_HELLO_REPLY_DELAY);
897
898 /* on NBMA network type, it happens to receive bidirectional Hello packet
899 without advance 1-Way Received event.
900 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
901 if (oi->type == OSPF_IFTYPE_NBMA &&
902 (old_state == NSM_Down || old_state == NSM_Attempt))
903 {
904 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
905 nbr->priority = hello->priority;
906 nbr->d_router = hello->d_router;
907 nbr->bd_router = hello->bd_router;
908 return;
909 }
910
paul68980082003-03-25 05:07:42 +0000911 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000912 size - OSPF_HELLO_MIN_SIZE))
913 {
914 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
915 nbr->options |= hello->options;
916 }
917 else
918 {
919 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
920 /* Set neighbor information. */
921 nbr->priority = hello->priority;
922 nbr->d_router = hello->d_router;
923 nbr->bd_router = hello->bd_router;
924 return;
925 }
926
927 /* If neighbor itself declares DR and no BDR exists,
928 cause event BackupSeen */
929 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
930 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
931 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
932
933 /* neighbor itself declares BDR. */
934 if (oi->state == ISM_Waiting &&
935 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
936 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
937
938 /* had not previously. */
939 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
940 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
941 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
942 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
943 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
944
945 /* had not previously. */
946 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
947 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
948 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
951
952 /* Neighbor priority check. */
953 if (nbr->priority >= 0 && nbr->priority != hello->priority)
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
955
956 /* Set neighbor information. */
957 nbr->priority = hello->priority;
958 nbr->d_router = hello->d_router;
959 nbr->bd_router = hello->bd_router;
960}
961
962/* Save DD flags/options/Seqnum received. */
963void
964ospf_db_desc_save_current (struct ospf_neighbor *nbr,
965 struct ospf_db_desc *dd)
966{
967 nbr->last_recv.flags = dd->flags;
968 nbr->last_recv.options = dd->options;
969 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
970}
971
972/* Process rest of DD packet. */
973static void
974ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
975 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
976 u_int16_t size)
977{
978 struct ospf_lsa *new, *find;
979 struct lsa_header *lsah;
980
paul9985f832005-02-09 15:51:56 +0000981 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000982 for (size -= OSPF_DB_DESC_MIN_SIZE;
983 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
984 {
985 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000986 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000987
988 /* Unknown LS type. */
989 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
990 {
ajsbec595a2004-11-30 22:38:43 +0000991 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000992 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
993 return;
994 }
995
996#ifdef HAVE_OPAQUE_LSA
997 if (IS_OPAQUE_LSA (lsah->type)
998 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
999 {
1000 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1001 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1002 return;
1003 }
1004#endif /* HAVE_OPAQUE_LSA */
1005
1006 switch (lsah->type)
1007 {
1008 case OSPF_AS_EXTERNAL_LSA:
1009#ifdef HAVE_OPAQUE_LSA
1010 case OSPF_OPAQUE_AS_LSA:
1011#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001012 /* Check for stub area. Reject if AS-External from stub but
1013 allow if from NSSA. */
1014 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001015 {
1016 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1017 lsah->type, inet_ntoa (lsah->id),
1018 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1019 "STUB" : "NSSA");
1020 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1021 return;
1022 }
1023 break;
1024 default:
1025 break;
1026 }
1027
1028 /* Create LS-request object. */
1029 new = ospf_ls_request_new (lsah);
1030
1031 /* Lookup received LSA, then add LS request list. */
1032 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1033 if (!find || ospf_lsa_more_recent (find, new) < 0)
1034 {
1035 ospf_ls_request_add (nbr, new);
1036 ospf_lsa_discard (new);
1037 }
1038 else
1039 {
1040 /* Received LSA is not recent. */
1041 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001042 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001043 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1044 ospf_lsa_discard (new);
1045 continue;
1046 }
1047 }
1048
1049 /* Master */
1050 if (IS_SET_DD_MS (nbr->dd_flags))
1051 {
1052 nbr->dd_seqnum++;
1053 /* Entire DD packet sent. */
1054 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1055 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1056 else
1057 /* Send new DD packet. */
1058 ospf_db_desc_send (nbr);
1059 }
1060 /* Slave */
1061 else
1062 {
1063 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1064
1065 /* When master's more flags is not set. */
1066 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1067 {
1068 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1069 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1070 }
1071
ajsbec595a2004-11-30 22:38:43 +00001072 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001073 ospf_db_desc_send (nbr);
1074 }
1075
1076 /* Save received neighbor values from DD. */
1077 ospf_db_desc_save_current (nbr, dd);
1078}
1079
1080int
1081ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1082{
1083 /* Is DD duplicated? */
1084 if (dd->options == nbr->last_recv.options &&
1085 dd->flags == nbr->last_recv.flags &&
1086 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1087 return 1;
1088
1089 return 0;
1090}
1091
1092/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001093static void
paul718e3742002-12-13 20:15:29 +00001094ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1095 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1096{
1097 struct ospf_db_desc *dd;
1098 struct ospf_neighbor *nbr;
1099
1100 /* Increment statistics. */
1101 oi->db_desc_in++;
1102
1103 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001104
pauld3f0d622004-05-05 15:27:15 +00001105 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001106 if (nbr == NULL)
1107 {
1108 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1109 inet_ntoa (ospfh->router_id));
1110 return;
1111 }
1112
1113 /* Check MTU. */
1114 if (ntohs (dd->mtu) > oi->ifp->mtu)
1115 {
ajs3aa8d5f2004-12-11 18:00:06 +00001116 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1117 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1118 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001119 return;
1120 }
1121
pauld363df22003-06-19 00:26:34 +00001122 /*
1123 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1124 * required. In fact at least JunOS sends DD packets with P bit clear.
1125 * Until proper solution is developped, this hack should help.
1126 *
1127 * Update: According to the RFCs, N bit is specified /only/ for Hello
1128 * options, unfortunately its use in DD options is not specified. Hence some
1129 * implementations follow E-bit semantics and set it in DD options, and some
1130 * treat it as unspecified and hence follow the directive "default for
1131 * options is clear", ie unset.
1132 *
1133 * Reset the flag, as ospfd follows E-bit semantics.
1134 */
1135 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1136 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1137 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1138 {
1139 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001140 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001141 inet_ntoa (nbr->router_id) );
1142 SET_FLAG (dd->options, OSPF_OPTION_NP);
1143 }
pauld363df22003-06-19 00:26:34 +00001144
paul718e3742002-12-13 20:15:29 +00001145#ifdef REJECT_IF_TBIT_ON
1146 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1147 {
1148 /*
1149 * In Hello protocol, optional capability must have checked
1150 * to prevent this T-bit enabled router be my neighbor.
1151 */
1152 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1153 return;
1154 }
1155#endif /* REJECT_IF_TBIT_ON */
1156
1157#ifdef HAVE_OPAQUE_LSA
1158 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001159 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001160 {
1161 /*
1162 * This node is not configured to handle O-bit, for now.
1163 * Clear it to ignore unsupported capability proposed by neighbor.
1164 */
1165 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1166 }
1167#endif /* HAVE_OPAQUE_LSA */
1168
1169 /* Process DD packet by neighbor status. */
1170 switch (nbr->state)
1171 {
1172 case NSM_Down:
1173 case NSM_Attempt:
1174 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001175 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001176 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001177 LOOKUP (ospf_nsm_state_msg, nbr->state));
1178 break;
1179 case NSM_Init:
1180 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1181 /* If the new state is ExStart, the processing of the current
1182 packet should then continue in this new state by falling
1183 through to case ExStart below. */
1184 if (nbr->state != NSM_ExStart)
1185 break;
1186 case NSM_ExStart:
1187 /* Initial DBD */
1188 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1189 (size == OSPF_DB_DESC_MIN_SIZE))
1190 {
paul68980082003-03-25 05:07:42 +00001191 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001192 {
1193 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001194 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001195 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001196 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1197 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1198 }
1199 else
1200 {
1201 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001202 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1203 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001204 break;
1205 }
1206 }
1207 /* Ack from the Slave */
1208 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1209 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001210 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001211 {
ajs17eaa722004-12-29 21:04:48 +00001212 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001213 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001214 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1215 }
1216 else
1217 {
ajs3aa8d5f2004-12-11 18:00:06 +00001218 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1219 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001220 break;
1221 }
1222
1223 /* This is where the real Options are saved */
1224 nbr->options = dd->options;
1225
1226#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001227 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001228 {
1229 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001230 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001231 inet_ntoa (nbr->router_id),
1232 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1233
1234 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1235 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1236 {
1237 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1238 /* This situation is undesirable, but not a real error. */
1239 }
1240 }
1241#endif /* HAVE_OPAQUE_LSA */
1242
1243 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1244
1245 /* continue processing rest of packet. */
1246 ospf_db_desc_proc (s, oi, nbr, dd, size);
1247 break;
1248 case NSM_Exchange:
1249 if (ospf_db_desc_is_dup (dd, nbr))
1250 {
1251 if (IS_SET_DD_MS (nbr->dd_flags))
1252 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001253 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1254 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001255 else
1256 /* Slave: cause to retransmit the last Database Description. */
1257 {
ajs3aa8d5f2004-12-11 18:00:06 +00001258 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1259 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001260 ospf_db_desc_resend (nbr);
1261 }
1262 break;
1263 }
1264
1265 /* Otherwise DD packet should be checked. */
1266 /* Check Master/Slave bit mismatch */
1267 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1268 {
ajs3aa8d5f2004-12-11 18:00:06 +00001269 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1270 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001271 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1272 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001273 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001274 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001275 break;
1276 }
1277
1278 /* Check initialize bit is set. */
1279 if (IS_SET_DD_I (dd->flags))
1280 {
ajs3aa8d5f2004-12-11 18:00:06 +00001281 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1282 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001283 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1284 break;
1285 }
1286
1287 /* Check DD Options. */
1288 if (dd->options != nbr->options)
1289 {
1290#ifdef ORIGINAL_CODING
1291 /* Save the new options for debugging */
1292 nbr->options = dd->options;
1293#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001294 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1295 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001296 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1297 break;
1298 }
1299
1300 /* Check DD sequence number. */
1301 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1302 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1303 (!IS_SET_DD_MS (nbr->dd_flags) &&
1304 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1305 {
ajs3aa8d5f2004-12-11 18:00:06 +00001306 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1307 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001308 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1309 break;
1310 }
1311
1312 /* Continue processing rest of packet. */
1313 ospf_db_desc_proc (s, oi, nbr, dd, size);
1314 break;
1315 case NSM_Loading:
1316 case NSM_Full:
1317 if (ospf_db_desc_is_dup (dd, nbr))
1318 {
1319 if (IS_SET_DD_MS (nbr->dd_flags))
1320 {
1321 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001322 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1323 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001324 break;
1325 }
1326 else
1327 {
1328 struct timeval t, now;
1329 gettimeofday (&now, NULL);
1330 t = tv_sub (now, nbr->last_send_ts);
1331 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1332 {
1333 /* In states Loading and Full the slave must resend
1334 its last Database Description packet in response to
1335 duplicate Database Description packets received
1336 from the master. For this reason the slave must
1337 wait RouterDeadInterval seconds before freeing the
1338 last Database Description packet. Reception of a
1339 Database Description packet from the master after
1340 this interval will generate a SeqNumberMismatch
1341 neighbor event. RFC2328 Section 10.8 */
1342 ospf_db_desc_resend (nbr);
1343 break;
1344 }
1345 }
1346 }
1347
1348 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1349 break;
1350 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001351 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1352 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001353 break;
1354 }
1355}
1356
1357#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1358
1359/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1360void
1361ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1362 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1363{
1364 struct ospf_neighbor *nbr;
1365 u_int32_t ls_type;
1366 struct in_addr ls_id;
1367 struct in_addr adv_router;
1368 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001369 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001370 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001371
1372 /* Increment statistics. */
1373 oi->ls_req_in++;
1374
pauld3f0d622004-05-05 15:27:15 +00001375 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001376 if (nbr == NULL)
1377 {
1378 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1379 inet_ntoa (ospfh->router_id));
1380 return;
1381 }
1382
1383 /* Neighbor State should be Exchange or later. */
1384 if (nbr->state != NSM_Exchange &&
1385 nbr->state != NSM_Loading &&
1386 nbr->state != NSM_Full)
1387 {
ajsbec595a2004-11-30 22:38:43 +00001388 zlog_warn ("Link State Request received from %s: "
1389 "Neighbor state is %s, packet discarded.",
1390 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001391 LOOKUP (ospf_nsm_state_msg, nbr->state));
1392 return;
1393 }
1394
1395 /* Send Link State Update for ALL requested LSAs. */
1396 ls_upd = list_new ();
1397 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1398
1399 while (size >= OSPF_LSA_KEY_SIZE)
1400 {
1401 /* Get one slice of Link State Request. */
1402 ls_type = stream_getl (s);
1403 ls_id.s_addr = stream_get_ipv4 (s);
1404 adv_router.s_addr = stream_get_ipv4 (s);
1405
1406 /* Verify LSA type. */
1407 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1408 {
1409 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1410 list_delete (ls_upd);
1411 return;
1412 }
1413
1414 /* Search proper LSA in LSDB. */
1415 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1416 if (find == NULL)
1417 {
1418 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1419 list_delete (ls_upd);
1420 return;
1421 }
1422
gdt86f1fd92005-01-10 14:20:43 +00001423 /* Packet overflows MTU size, send immediately. */
1424 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001425 {
1426 if (oi->type == OSPF_IFTYPE_NBMA)
1427 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1428 else
1429 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1430
1431 /* Only remove list contents. Keep ls_upd. */
1432 list_delete_all_node (ls_upd);
1433
1434 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1435 }
1436
1437 /* Append LSA to update list. */
1438 listnode_add (ls_upd, find);
1439 length += ntohs (find->data->length);
1440
1441 size -= OSPF_LSA_KEY_SIZE;
1442 }
1443
1444 /* Send rest of Link State Update. */
1445 if (listcount (ls_upd) > 0)
1446 {
1447 if (oi->type == OSPF_IFTYPE_NBMA)
1448 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1449 else
1450 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1451
1452 list_delete (ls_upd);
1453 }
1454 else
1455 list_free (ls_upd);
1456}
1457
1458/* Get the list of LSAs from Link State Update packet.
1459 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001460static struct list *
paul718e3742002-12-13 20:15:29 +00001461ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1462 struct ospf_interface *oi, size_t size)
1463{
1464 u_int16_t count, sum;
1465 u_int32_t length;
1466 struct lsa_header *lsah;
1467 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001468 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001469
1470 lsas = list_new ();
1471
1472 count = stream_getl (s);
1473 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1474
1475 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001476 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001477 {
1478 lsah = (struct lsa_header *) STREAM_PNT (s);
1479 length = ntohs (lsah->length);
1480
1481 if (length > size)
1482 {
1483 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1484 break;
1485 }
1486
1487 /* Validate the LSA's LS checksum. */
1488 sum = lsah->checksum;
1489 if (sum != ospf_lsa_checksum (lsah))
1490 {
1491 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1492 sum, lsah->checksum);
1493 continue;
1494 }
1495
1496 /* Examine the LSA's LS type. */
1497 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1498 {
1499 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1500 continue;
1501 }
1502
1503 /*
1504 * What if the received LSA's age is greater than MaxAge?
1505 * Treat it as a MaxAge case -- endo.
1506 */
1507 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1508 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1509
1510#ifdef HAVE_OPAQUE_LSA
1511 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1512 {
1513#ifdef STRICT_OBIT_USAGE_CHECK
1514 if ((IS_OPAQUE_LSA(lsah->type) &&
1515 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1516 || (! IS_OPAQUE_LSA(lsah->type) &&
1517 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1518 {
1519 /*
1520 * This neighbor must know the exact usage of O-bit;
1521 * the bit will be set in Type-9,10,11 LSAs only.
1522 */
1523 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1524 continue;
1525 }
1526#endif /* STRICT_OBIT_USAGE_CHECK */
1527
1528 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1529 if (lsah->type == OSPF_OPAQUE_AS_LSA
1530 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1531 {
1532 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001533 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 +00001534 continue;
1535 }
1536 }
1537 else if (IS_OPAQUE_LSA(lsah->type))
1538 {
1539 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1540 continue;
1541 }
1542#endif /* HAVE_OPAQUE_LSA */
1543
1544 /* Create OSPF LSA instance. */
1545 lsa = ospf_lsa_new ();
1546
1547 /* We may wish to put some error checking if type NSSA comes in
1548 and area not in NSSA mode */
1549 switch (lsah->type)
1550 {
1551 case OSPF_AS_EXTERNAL_LSA:
1552#ifdef HAVE_OPAQUE_LSA
1553 case OSPF_OPAQUE_AS_LSA:
1554 lsa->area = NULL;
1555 break;
1556 case OSPF_OPAQUE_LINK_LSA:
1557 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1558 /* Fallthrough */
1559#endif /* HAVE_OPAQUE_LSA */
1560 default:
1561 lsa->area = oi->area;
1562 break;
1563 }
1564
1565 lsa->data = ospf_lsa_data_new (length);
1566 memcpy (lsa->data, lsah, length);
1567
1568 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001569 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001570 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1571 listnode_add (lsas, lsa);
1572 }
1573
1574 return lsas;
1575}
1576
1577/* Cleanup Update list. */
1578void
hasso52dc7ee2004-09-23 19:18:23 +00001579ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001580{
hasso52dc7ee2004-09-23 19:18:23 +00001581 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001582 struct ospf_lsa *lsa;
1583
1584 for (node = listhead (lsas); node; nextnode (node))
1585 if ((lsa = getdata (node)) != NULL)
1586 ospf_lsa_discard (lsa);
1587
1588 list_delete (lsas);
1589}
1590
1591/* OSPF Link State Update message read -- RFC2328 Section 13. */
1592void
1593ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1594 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1595{
1596 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001597 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001598#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001599 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001600#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001601 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001602 struct ospf_lsa *lsa = NULL;
1603 /* unsigned long ls_req_found = 0; */
1604
1605 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1606
1607 /* Increment statistics. */
1608 oi->ls_upd_in++;
1609
1610 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001611 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001612 if (nbr == NULL)
1613 {
1614 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1615 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1616 return;
1617 }
1618
1619 /* Check neighbor state. */
1620 if (nbr->state < NSM_Exchange)
1621 {
ajs3aa8d5f2004-12-11 18:00:06 +00001622 zlog_warn ("Link State Update: "
1623 "Neighbor[%s] state %s is less than Exchange",
1624 inet_ntoa (ospfh->router_id),
1625 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001626 return;
1627 }
1628
1629 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1630 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1631 * of section 13.
1632 */
1633 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1634
1635#ifdef HAVE_OPAQUE_LSA
1636 /*
1637 * Prepare two kinds of lists to clean up unwanted self-originated
1638 * Opaque-LSAs from the routing domain as soon as possible.
1639 */
1640 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1641 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1642
1643 /*
1644 * If self-originated Opaque-LSAs that have flooded before restart
1645 * are contained in the received LSUpd message, corresponding LSReq
1646 * messages to be sent may have to be modified.
1647 * To eliminate possible race conditions such that flushing and normal
1648 * updating for the same LSA would take place alternately, this trick
1649 * must be done before entering to the loop below.
1650 */
1651 ospf_opaque_adjust_lsreq (nbr, lsas);
1652#endif /* HAVE_OPAQUE_LSA */
1653
1654#define DISCARD_LSA(L,N) {\
1655 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001656 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 +00001657 ospf_lsa_discard (L); \
1658 continue; }
1659
1660 /* Process each LSA received in the one packet. */
1661 for (node = listhead (lsas); node; node = next)
1662 {
1663 struct ospf_lsa *ls_ret, *current;
1664 int ret = 1;
1665
1666 next = node->next;
1667
1668 lsa = getdata (node);
1669
paul718e3742002-12-13 20:15:29 +00001670 if (IS_DEBUG_OSPF_NSSA)
1671 {
1672 char buf1[INET_ADDRSTRLEN];
1673 char buf2[INET_ADDRSTRLEN];
1674 char buf3[INET_ADDRSTRLEN];
1675
ajs2a42e282004-12-08 18:43:03 +00001676 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001677 lsa->data->type,
1678 inet_ntop (AF_INET, &ospfh->router_id,
1679 buf1, INET_ADDRSTRLEN),
1680 inet_ntop (AF_INET, &lsa->data->id,
1681 buf2, INET_ADDRSTRLEN),
1682 inet_ntop (AF_INET, &lsa->data->adv_router,
1683 buf3, INET_ADDRSTRLEN));
1684 }
paul718e3742002-12-13 20:15:29 +00001685
1686 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1687
1688 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1689
1690 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1691
1692 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1693
1694 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1695
1696 /* Do take in Type-7's if we are an NSSA */
1697
1698 /* If we are also an ABR, later translate them to a Type-5 packet */
1699
1700 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1701 translate them to a separate Type-5 packet. */
1702
1703 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1704 /* Reject from STUB or NSSA */
1705 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1706 {
1707 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001708 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001709 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001710 }
1711
paul718e3742002-12-13 20:15:29 +00001712 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1713 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1714 {
1715 DISCARD_LSA (lsa,2);
1716 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001717 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001718 }
paul718e3742002-12-13 20:15:29 +00001719
1720 /* Find the LSA in the current database. */
1721
1722 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1723
1724 /* If the LSA's LS age is equal to MaxAge, and there is currently
1725 no instance of the LSA in the router's link state database,
1726 and none of router's neighbors are in states Exchange or Loading,
1727 then take the following actions. */
1728
1729 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001730 (ospf_nbr_count (oi, NSM_Exchange) +
1731 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001732 {
1733 /* Response Link State Acknowledgment. */
1734 ospf_ls_ack_send (nbr, lsa);
1735
1736 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001737 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1738 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001739 DISCARD_LSA (lsa, 3);
1740 }
1741
1742#ifdef HAVE_OPAQUE_LSA
1743 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001744 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001745 {
1746 /*
1747 * Even if initial flushing seems to be completed, there might
1748 * be a case that self-originated LSA with MaxAge still remain
1749 * in the routing domain.
1750 * Just send an LSAck message to cease retransmission.
1751 */
1752 if (IS_LSA_MAXAGE (lsa))
1753 {
1754 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1755 ospf_ls_ack_send (nbr, lsa);
1756 ospf_lsa_discard (lsa);
1757
1758 if (current != NULL && ! IS_LSA_MAXAGE (current))
1759 ospf_opaque_lsa_refresh_schedule (current);
1760 continue;
1761 }
1762
1763 /*
1764 * If an instance of self-originated Opaque-LSA is not found
1765 * in the LSDB, there are some possible cases here.
1766 *
1767 * 1) This node lost opaque-capability after restart.
1768 * 2) Else, a part of opaque-type is no more supported.
1769 * 3) Else, a part of opaque-id is no more supported.
1770 *
1771 * Anyway, it is still this node's responsibility to flush it.
1772 * Otherwise, the LSA instance remains in the routing domain
1773 * until its age reaches to MaxAge.
1774 */
1775 if (current == NULL)
1776 {
1777 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001778 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001779
1780 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1781 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1782 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1783 continue;
1784 }
1785 }
1786#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001787 /* It might be happen that received LSA is self-originated network LSA, but
1788 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1789 * Link State ID is one of the router's own IP interface addresses but whose
1790 * Advertising Router is not equal to the router's own Router ID
1791 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1792 */
1793
1794 if(lsa->data->type == OSPF_NETWORK_LSA)
1795 {
hasso52dc7ee2004-09-23 19:18:23 +00001796 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001797 int Flag = 0;
1798
1799 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1800 {
1801 struct ospf_interface *out_if = getdata(oi_node);
1802 if(out_if == NULL)
1803 break;
1804
1805 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1806 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1807 {
1808 if(out_if->network_lsa_self)
1809 {
1810 ospf_lsa_flush_area(lsa,out_if->area);
1811 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001812 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001813 lsa, (int) lsa->data->type);
1814 ospf_lsa_discard (lsa);
1815 Flag = 1;
1816 }
1817 break;
1818 }
1819 }
1820 if(Flag)
1821 continue;
1822 }
paul718e3742002-12-13 20:15:29 +00001823
1824 /* (5) Find the instance of this LSA that is currently contained
1825 in the router's link state database. If there is no
1826 database copy, or the received LSA is more recent than
1827 the database copy the following steps must be performed. */
1828
1829 if (current == NULL ||
1830 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1831 {
1832 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001833 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001834 DISCARD_LSA (lsa, 4);
1835 continue;
1836 }
1837
1838 /* (6) Else, If there is an instance of the LSA on the sending
1839 neighbor's Link state request list, an error has occurred in
1840 the Database Exchange process. In this case, restart the
1841 Database Exchange process by generating the neighbor event
1842 BadLSReq for the sending neighbor and stop processing the
1843 Link State Update packet. */
1844
1845 if (ospf_ls_request_lookup (nbr, lsa))
1846 {
1847 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001848 zlog_warn("LSA[%s] instance exists on Link state request list",
1849 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001850
1851 /* Clean list of LSAs. */
1852 ospf_upd_list_clean (lsas);
1853 /* this lsa is not on lsas list already. */
1854 ospf_lsa_discard (lsa);
1855#ifdef HAVE_OPAQUE_LSA
1856 list_delete (mylsa_acks);
1857 list_delete (mylsa_upds);
1858#endif /* HAVE_OPAQUE_LSA */
1859 return;
1860 }
1861
1862 /* If the received LSA is the same instance as the database copy
1863 (i.e., neither one is more recent) the following two steps
1864 should be performed: */
1865
1866 if (ret == 0)
1867 {
1868 /* If the LSA is listed in the Link state retransmission list
1869 for the receiving adjacency, the router itself is expecting
1870 an acknowledgment for this LSA. The router should treat the
1871 received LSA as an acknowledgment by removing the LSA from
1872 the Link state retransmission list. This is termed an
1873 "implied acknowledgment". */
1874
1875 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1876
1877 if (ls_ret != NULL)
1878 {
1879 ospf_ls_retransmit_delete (nbr, ls_ret);
1880
1881 /* Delayed acknowledgment sent if advertisement received
1882 from Designated Router, otherwise do nothing. */
1883 if (oi->state == ISM_Backup)
1884 if (NBR_IS_DR (nbr))
1885 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1886
1887 DISCARD_LSA (lsa, 5);
1888 }
1889 else
1890 /* Acknowledge the receipt of the LSA by sending a
1891 Link State Acknowledgment packet back out the receiving
1892 interface. */
1893 {
1894 ospf_ls_ack_send (nbr, lsa);
1895 DISCARD_LSA (lsa, 6);
1896 }
1897 }
1898
1899 /* The database copy is more recent. If the database copy
1900 has LS age equal to MaxAge and LS sequence number equal to
1901 MaxSequenceNumber, simply discard the received LSA without
1902 acknowledging it. (In this case, the LSA's LS sequence number is
1903 wrapping, and the MaxSequenceNumber LSA must be completely
1904 flushed before any new LSA instance can be introduced). */
1905
1906 else if (ret > 0) /* Database copy is more recent */
1907 {
1908 if (IS_LSA_MAXAGE (current) &&
1909 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1910 {
1911 DISCARD_LSA (lsa, 7);
1912 }
1913 /* Otherwise, as long as the database copy has not been sent in a
1914 Link State Update within the last MinLSArrival seconds, send the
1915 database copy back to the sending neighbor, encapsulated within
1916 a Link State Update Packet. The Link State Update Packet should
1917 be sent directly to the neighbor. In so doing, do not put the
1918 database copy of the LSA on the neighbor's link state
1919 retransmission list, and do not acknowledge the received (less
1920 recent) LSA instance. */
1921 else
1922 {
1923 struct timeval now;
1924
1925 gettimeofday (&now, NULL);
1926
1927 if (tv_cmp (tv_sub (now, current->tv_orig),
1928 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1929 /* Trap NSSA type later.*/
1930 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1931 DISCARD_LSA (lsa, 8);
1932 }
1933 }
1934 }
1935
1936#ifdef HAVE_OPAQUE_LSA
1937 /*
1938 * Now that previously originated Opaque-LSAs those which not yet
1939 * installed into LSDB are captured, take several steps to clear
1940 * them completely from the routing domain, before proceeding to
1941 * origination for the current target Opaque-LSAs.
1942 */
1943 while (listcount (mylsa_acks) > 0)
1944 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1945
1946 if (listcount (mylsa_upds) > 0)
1947 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1948
1949 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001950 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001951#endif /* HAVE_OPAQUE_LSA */
1952
1953 assert (listcount (lsas) == 0);
1954 list_delete (lsas);
1955}
1956
1957/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1958void
1959ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1960 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1961{
1962 struct ospf_neighbor *nbr;
1963#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001964 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001965#endif /* HAVE_OPAQUE_LSA */
1966
1967 /* increment statistics. */
1968 oi->ls_ack_in++;
1969
pauld3f0d622004-05-05 15:27:15 +00001970 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001971 if (nbr == NULL)
1972 {
1973 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1974 inet_ntoa (ospfh->router_id));
1975 return;
1976 }
1977
1978 if (nbr->state < NSM_Exchange)
1979 {
ajs3aa8d5f2004-12-11 18:00:06 +00001980 zlog_warn ("Link State Acknowledgment: "
1981 "Neighbor[%s] state %s is less than Exchange",
1982 inet_ntoa (ospfh->router_id),
1983 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001984 return;
1985 }
1986
1987#ifdef HAVE_OPAQUE_LSA
1988 opaque_acks = list_new ();
1989#endif /* HAVE_OPAQUE_LSA */
1990
1991 while (size >= OSPF_LSA_HEADER_SIZE)
1992 {
1993 struct ospf_lsa *lsa, *lsr;
1994
1995 lsa = ospf_lsa_new ();
1996 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1997
1998 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1999 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002000 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002001
2002 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2003 {
2004 lsa->data = NULL;
2005 ospf_lsa_discard (lsa);
2006 continue;
2007 }
2008
2009 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2010
2011 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2012 {
2013#ifdef HAVE_OPAQUE_LSA
2014 /* Keep this LSA entry for later reference. */
2015 if (IS_OPAQUE_LSA (lsr->data->type))
2016 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2017#endif /* HAVE_OPAQUE_LSA */
2018
2019 ospf_ls_retransmit_delete (nbr, lsr);
2020 }
2021
2022 lsa->data = NULL;
2023 ospf_lsa_discard (lsa);
2024 }
2025
2026#ifdef HAVE_OPAQUE_LSA
2027 if (listcount (opaque_acks) > 0)
2028 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2029
2030 list_delete (opaque_acks);
2031 return;
2032#endif /* HAVE_OPAQUE_LSA */
2033}
2034
ajs038163f2005-02-17 19:55:59 +00002035static struct stream *
ajs5c333492005-02-23 15:43:01 +00002036ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002037{
2038 int ret;
ajs5c333492005-02-23 15:43:01 +00002039 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002040 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002041 unsigned int ifindex = 0;
2042 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002043 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002044 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002045 struct msghdr msgh;
2046
paul68defd62004-09-27 07:27:13 +00002047 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002048 msgh.msg_iov = &iov;
2049 msgh.msg_iovlen = 1;
2050 msgh.msg_control = (caddr_t) buff;
2051 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002052
ajs5c333492005-02-23 15:43:01 +00002053 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2054 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002055 {
ajs5c333492005-02-23 15:43:01 +00002056 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2057 return NULL;
2058 }
2059 if (ret < sizeof(iph))
2060 {
2061 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2062 "(ip header size is %u)",
2063 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002064 return NULL;
2065 }
paul18b12c32004-10-05 14:38:29 +00002066
ajs5c333492005-02-23 15:43:01 +00002067 /* Note that there should not be alignment problems with this assignment
2068 because this is at the beginning of the stream data buffer. */
2069 iph = (struct ip *) STREAM_DATA(ibuf);
2070 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002071
ajs5c333492005-02-23 15:43:01 +00002072 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002073
paul239aecc2003-12-08 10:34:54 +00002074#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002075 /*
2076 * Kernel network code touches incoming IP header parameters,
2077 * before protocol specific processing.
2078 *
2079 * 1) Convert byteorder to host representation.
2080 * --> ip_len, ip_id, ip_off
2081 *
2082 * 2) Adjust ip_len to strip IP header size!
2083 * --> If user process receives entire IP packet via RAW
2084 * socket, it must consider adding IP header size to
2085 * the "ip_len" field of "ip" structure.
2086 *
2087 * For more details, see <netinet/ip_input.c>.
2088 */
ajs5c333492005-02-23 15:43:01 +00002089 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002090#endif
2091
paul863082d2004-08-19 04:43:43 +00002092 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002093
2094 *ifp = if_lookup_by_index (ifindex);
2095
2096 if (ret != ip_len)
2097 {
ajs5c333492005-02-23 15:43:01 +00002098 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2099 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002100 return NULL;
2101 }
2102
2103 return ibuf;
2104}
2105
2106struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002107ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002108 struct ip *iph, struct ospf_header *ospfh)
2109{
2110 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002111 struct ospf_vl_data *vl_data;
2112 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002113 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002114
2115 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2116 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002117 return NULL;
paul718e3742002-12-13 20:15:29 +00002118
pauld3f0d622004-05-05 15:27:15 +00002119 /* look for local OSPF interface matching the destination
2120 * to determine Area ID. We presume therefore the destination address
2121 * is unique, or at least (for "unnumbered" links), not used in other
2122 * areas
2123 */
2124 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2125 iph->ip_dst)) == NULL)
2126 return NULL;
paul718e3742002-12-13 20:15:29 +00002127
paul020709f2003-04-04 02:44:16 +00002128 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002129 {
2130 if ((vl_data = getdata (node)) == NULL)
2131 continue;
2132
paul020709f2003-04-04 02:44:16 +00002133 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002134 if (!vl_area)
2135 continue;
2136
2137 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2138 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2139 {
2140 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002141 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002142 IF_NAME (vl_data->vl_oi));
2143 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2144 {
2145 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002146 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002147 return NULL;
2148 }
2149
2150 return vl_data->vl_oi;
2151 }
2152 }
2153
2154 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002155 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002156
pauld3f0d622004-05-05 15:27:15 +00002157 return NULL;
paul718e3742002-12-13 20:15:29 +00002158}
2159
2160int
2161ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2162{
2163 /* Check match the Area ID of the receiving interface. */
2164 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2165 return 1;
2166
2167 return 0;
2168}
2169
2170/* Unbound socket will accept any Raw IP packets if proto is matched.
2171 To prevent it, compare src IP address and i/f address with masking
2172 i/f network mask. */
2173int
2174ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2175{
2176 struct in_addr mask, me, him;
2177
2178 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2179 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2180 return 1;
2181
2182 masklen2ip (oi->address->prefixlen, &mask);
2183
2184 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2185 him.s_addr = ip_src.s_addr & mask.s_addr;
2186
2187 if (IPV4_ADDR_SAME (&me, &him))
2188 return 1;
2189
2190 return 0;
2191}
2192
2193int
2194ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2195 struct ospf_header *ospfh)
2196{
2197 int ret = 0;
2198 struct crypt_key *ck;
2199
2200 switch (ntohs (ospfh->auth_type))
2201 {
2202 case OSPF_AUTH_NULL:
2203 ret = 1;
2204 break;
2205 case OSPF_AUTH_SIMPLE:
2206 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2207 ret = 1;
2208 else
2209 ret = 0;
2210 break;
2211 case OSPF_AUTH_CRYPTOGRAPHIC:
2212 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2213 {
2214 ret = 0;
2215 break;
2216 }
2217
2218 /* This is very basic, the digest processing is elsewhere */
2219 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2220 ospfh->u.crypt.key_id == ck->key_id &&
2221 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2222 ret = 1;
2223 else
2224 ret = 0;
2225 break;
2226 default:
2227 ret = 0;
2228 break;
2229 }
2230
2231 return ret;
2232}
2233
2234int
2235ospf_check_sum (struct ospf_header *ospfh)
2236{
2237 u_int32_t ret;
2238 u_int16_t sum;
2239 int in_cksum (void *ptr, int nbytes);
2240
2241 /* clear auth_data for checksum. */
2242 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2243
2244 /* keep checksum and clear. */
2245 sum = ospfh->checksum;
2246 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2247
2248 /* calculate checksum. */
2249 ret = in_cksum (ospfh, ntohs (ospfh->length));
2250
2251 if (ret != sum)
2252 {
2253 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2254 ret, sum);
2255 return 0;
2256 }
2257
2258 return 1;
2259}
2260
2261/* OSPF Header verification. */
2262int
2263ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2264 struct ip *iph, struct ospf_header *ospfh)
2265{
2266 /* check version. */
2267 if (ospfh->version != OSPF_VERSION)
2268 {
2269 zlog_warn ("interface %s: ospf_read version number mismatch.",
2270 IF_NAME (oi));
2271 return -1;
2272 }
2273
2274 /* Check Area ID. */
2275 if (!ospf_check_area_id (oi, ospfh))
2276 {
2277 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2278 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2279 return -1;
2280 }
2281
2282 /* Check network mask, Silently discarded. */
2283 if (! ospf_check_network_mask (oi, iph->ip_src))
2284 {
2285 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2286 IF_NAME (oi), inet_ntoa (iph->ip_src));
2287 return -1;
2288 }
2289
2290 /* Check authentication. */
2291 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2292 {
2293 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2294 IF_NAME (oi));
2295 return -1;
2296 }
2297
2298 if (! ospf_check_auth (oi, ibuf, ospfh))
2299 {
2300 zlog_warn ("interface %s: ospf_read authentication failed.",
2301 IF_NAME (oi));
2302 return -1;
2303 }
2304
2305 /* if check sum is invalid, packet is discarded. */
2306 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2307 {
2308 if (! ospf_check_sum (ospfh))
2309 {
2310 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2311 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2312 return -1;
2313 }
2314 }
2315 else
2316 {
2317 if (ospfh->checksum != 0)
2318 return -1;
2319 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2320 {
2321 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2322 IF_NAME (oi));
2323 return -1;
2324 }
2325 }
2326
2327 return 0;
2328}
2329
2330/* Starting point of packet process function. */
2331int
2332ospf_read (struct thread *thread)
2333{
2334 int ret;
2335 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002336 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002337 struct ospf_interface *oi;
2338 struct ip *iph;
2339 struct ospf_header *ospfh;
2340 u_int16_t length;
2341 struct interface *ifp;
2342
2343 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002344 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002345
2346 /* prepare for next packet. */
2347 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002348
2349 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002350 stream_reset(ospf->ibuf);
2351 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002352 return -1;
2353
ajs5c333492005-02-23 15:43:01 +00002354 /* Note that there should not be alignment problems with this assignment
2355 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002356 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002357 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002358
paulac191232004-10-22 12:05:17 +00002359 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002360 /* Handle cases where the platform does not support retrieving the ifindex,
2361 and also platforms (such as Solaris 8) that claim to support ifindex
2362 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002363 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002364
pauld3f0d622004-05-05 15:27:15 +00002365 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002366 return 0;
paul718e3742002-12-13 20:15:29 +00002367
2368 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002369 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002370 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002371
paul718e3742002-12-13 20:15:29 +00002372 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002373 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002374 {
pauld3241812003-09-29 12:42:39 +00002375 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2376 {
ajs2a42e282004-12-08 18:43:03 +00002377 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002378 inet_ntoa (iph->ip_src));
2379 }
paul718e3742002-12-13 20:15:29 +00002380 return 0;
2381 }
2382
2383 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002384 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002385
2386 /* Get ospf packet header. */
2387 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2388
2389 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002390 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002391
2392 /* if no local ospf_interface,
2393 * or header area is backbone but ospf_interface is not
2394 * check for VLINK interface
2395 */
2396 if ( (oi == NULL) ||
2397 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2398 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2399 )
2400 {
2401 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2402 {
2403 zlog_warn ("Packet from [%s] received on link %s"
2404 " but no ospf_interface",
2405 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002406 return 0;
2407 }
2408 }
2409
2410 /* else it must be a local ospf interface, check it was received on
2411 * correct link
2412 */
2413 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002414 {
2415 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002416 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002417 return 0;
2418 }
ajs847947f2005-02-02 18:38:48 +00002419 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002420 {
ajsba6454e2005-02-08 15:37:30 +00002421 char buf[2][INET_ADDRSTRLEN];
2422 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002423 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002424 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2425 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2426 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002427 /* Fix multicast memberships? */
2428 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2429 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2430 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2431 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2432 if (oi->multicast_memberships)
2433 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002434 return 0;
2435 }
paul718e3742002-12-13 20:15:29 +00002436
2437 /*
2438 * If the received packet is destined for AllDRouters, the packet
2439 * should be accepted only if the received ospf interface state is
2440 * either DR or Backup -- endo.
2441 */
2442 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2443 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2444 {
ajsba6454e2005-02-08 15:37:30 +00002445 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002446 inet_ntoa (iph->ip_src), IF_NAME (oi),
2447 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002448 /* Try to fix multicast membership. */
2449 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2450 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002451 return 0;
2452 }
2453
2454 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002455 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2456 {
paul718e3742002-12-13 20:15:29 +00002457 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002458 {
ajs2a42e282004-12-08 18:43:03 +00002459 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002460 ospf_packet_dump (ibuf);
2461 }
paul718e3742002-12-13 20:15:29 +00002462
ajs2a42e282004-12-08 18:43:03 +00002463 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002464 ospf_packet_type_str[ospfh->type],
2465 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002466 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2467 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002468
2469 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002470 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002471 }
paul718e3742002-12-13 20:15:29 +00002472
2473 /* Some header verification. */
2474 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2475 if (ret < 0)
2476 {
pauld3241812003-09-29 12:42:39 +00002477 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2478 {
ajs2a42e282004-12-08 18:43:03 +00002479 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002480 "dropping.",
2481 ospf_packet_type_str[ospfh->type],
2482 inet_ntoa (iph->ip_src));
2483 }
paul718e3742002-12-13 20:15:29 +00002484 return ret;
2485 }
2486
paul9985f832005-02-09 15:51:56 +00002487 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002488
2489 /* Adjust size to message length. */
2490 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2491
2492 /* Read rest of the packet and call each sort of packet routine. */
2493 switch (ospfh->type)
2494 {
2495 case OSPF_MSG_HELLO:
2496 ospf_hello (iph, ospfh, ibuf, oi, length);
2497 break;
2498 case OSPF_MSG_DB_DESC:
2499 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2500 break;
2501 case OSPF_MSG_LS_REQ:
2502 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2503 break;
2504 case OSPF_MSG_LS_UPD:
2505 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2506 break;
2507 case OSPF_MSG_LS_ACK:
2508 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2509 break;
2510 default:
2511 zlog (NULL, LOG_WARNING,
2512 "interface %s: OSPF packet header type %d is illegal",
2513 IF_NAME (oi), ospfh->type);
2514 break;
2515 }
2516
paul718e3742002-12-13 20:15:29 +00002517 return 0;
2518}
2519
2520/* Make OSPF header. */
2521void
2522ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2523{
2524 struct ospf_header *ospfh;
2525
2526 ospfh = (struct ospf_header *) STREAM_DATA (s);
2527
2528 ospfh->version = (u_char) OSPF_VERSION;
2529 ospfh->type = (u_char) type;
2530
paul68980082003-03-25 05:07:42 +00002531 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002532
2533 ospfh->checksum = 0;
2534 ospfh->area_id = oi->area->area_id;
2535 ospfh->auth_type = htons (ospf_auth_type (oi));
2536
2537 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2538
paul9985f832005-02-09 15:51:56 +00002539 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002540}
2541
2542/* Make Authentication Data. */
2543int
2544ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2545{
2546 struct crypt_key *ck;
2547
2548 switch (ospf_auth_type (oi))
2549 {
2550 case OSPF_AUTH_NULL:
2551 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2552 break;
2553 case OSPF_AUTH_SIMPLE:
2554 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2555 OSPF_AUTH_SIMPLE_SIZE);
2556 break;
2557 case OSPF_AUTH_CRYPTOGRAPHIC:
2558 /* If key is not set, then set 0. */
2559 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2560 {
2561 ospfh->u.crypt.zero = 0;
2562 ospfh->u.crypt.key_id = 0;
2563 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2564 }
2565 else
2566 {
2567 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2568 ospfh->u.crypt.zero = 0;
2569 ospfh->u.crypt.key_id = ck->key_id;
2570 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2571 }
2572 /* note: the seq is done in ospf_make_md5_digest() */
2573 break;
2574 default:
2575 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2576 break;
2577 }
2578
2579 return 0;
2580}
2581
2582/* Fill rest of OSPF header. */
2583void
2584ospf_fill_header (struct ospf_interface *oi,
2585 struct stream *s, u_int16_t length)
2586{
2587 struct ospf_header *ospfh;
2588
2589 ospfh = (struct ospf_header *) STREAM_DATA (s);
2590
2591 /* Fill length. */
2592 ospfh->length = htons (length);
2593
2594 /* Calculate checksum. */
2595 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2596 ospfh->checksum = in_cksum (ospfh, length);
2597 else
2598 ospfh->checksum = 0;
2599
2600 /* Add Authentication Data. */
2601 ospf_make_auth (oi, ospfh);
2602}
2603
2604int
2605ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2606{
2607 struct ospf_neighbor *nbr;
2608 struct route_node *rn;
2609 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2610 struct in_addr mask;
2611 unsigned long p;
2612 int flag = 0;
2613
2614 /* Set netmask of interface. */
2615 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2616 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2617 masklen2ip (oi->address->prefixlen, &mask);
2618 else
2619 memset ((char *) &mask, 0, sizeof (struct in_addr));
2620 stream_put_ipv4 (s, mask.s_addr);
2621
2622 /* Set Hello Interval. */
2623 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2624
2625 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002626 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002627 OPTIONS(oi), IF_NAME (oi));
2628
2629 /* Set Options. */
2630 stream_putc (s, OPTIONS (oi));
2631
2632 /* Set Router Priority. */
2633 stream_putc (s, PRIORITY (oi));
2634
2635 /* Set Router Dead Interval. */
2636 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2637
2638 /* Set Designated Router. */
2639 stream_put_ipv4 (s, DR (oi).s_addr);
2640
paul9985f832005-02-09 15:51:56 +00002641 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002642
2643 /* Set Backup Designated Router. */
2644 stream_put_ipv4 (s, BDR (oi).s_addr);
2645
2646 /* Add neighbor seen. */
2647 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002648 if ((nbr = rn->info))
2649 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2650 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2651 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2652 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002653 {
2654 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002655 if (nbr->d_router.s_addr != 0
2656 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2657 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2658 flag = 1;
paul718e3742002-12-13 20:15:29 +00002659
2660 stream_put_ipv4 (s, nbr->router_id.s_addr);
2661 length += 4;
2662 }
2663
2664 /* Let neighbor generate BackupSeen. */
2665 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002666 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002667
2668 return length;
2669}
2670
2671int
2672ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2673 struct stream *s)
2674{
2675 struct ospf_lsa *lsa;
2676 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2677 u_char options;
2678 unsigned long pp;
2679 int i;
2680 struct ospf_lsdb *lsdb;
2681
2682 /* Set Interface MTU. */
2683 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2684 stream_putw (s, 0);
2685 else
2686 stream_putw (s, oi->ifp->mtu);
2687
2688 /* Set Options. */
2689 options = OPTIONS (oi);
2690#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002691 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002692 {
2693 if (IS_SET_DD_I (nbr->dd_flags)
2694 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2695 /*
2696 * Set O-bit in the outgoing DD packet for capablity negotiation,
2697 * if one of following case is applicable.
2698 *
2699 * 1) WaitTimer expiration event triggered the neighbor state to
2700 * change to Exstart, but no (valid) DD packet has received
2701 * from the neighbor yet.
2702 *
2703 * 2) At least one DD packet with O-bit on has received from the
2704 * neighbor.
2705 */
2706 SET_FLAG (options, OSPF_OPTION_O);
2707 }
2708#endif /* HAVE_OPAQUE_LSA */
2709 stream_putc (s, options);
2710
2711 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002712 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002713 stream_putc (s, nbr->dd_flags);
2714
2715 /* Set DD Sequence Number. */
2716 stream_putl (s, nbr->dd_seqnum);
2717
2718 if (ospf_db_summary_isempty (nbr))
2719 {
2720 if (nbr->state >= NSM_Exchange)
2721 {
2722 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2723 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002724 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002725 }
2726 return length;
2727 }
2728
2729 /* Describe LSA Header from Database Summary List. */
2730 lsdb = &nbr->db_sum;
2731
2732 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2733 {
2734 struct route_table *table = lsdb->type[i].db;
2735 struct route_node *rn;
2736
2737 for (rn = route_top (table); rn; rn = route_next (rn))
2738 if ((lsa = rn->info) != NULL)
2739 {
2740#ifdef HAVE_OPAQUE_LSA
2741 if (IS_OPAQUE_LSA (lsa->data->type)
2742 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2743 {
2744 /* Suppress advertising opaque-informations. */
2745 /* Remove LSA from DB summary list. */
2746 ospf_lsdb_delete (lsdb, lsa);
2747 continue;
2748 }
2749#endif /* HAVE_OPAQUE_LSA */
2750
2751 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2752 {
2753 struct lsa_header *lsah;
2754 u_int16_t ls_age;
2755
2756 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002757 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002758 break;
2759
2760 /* Keep pointer to LS age. */
2761 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002762 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002763
2764 /* Proceed stream pointer. */
2765 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2766 length += OSPF_LSA_HEADER_SIZE;
2767
2768 /* Set LS age. */
2769 ls_age = LS_AGE (lsa);
2770 lsah->ls_age = htons (ls_age);
2771
2772 }
2773
2774 /* Remove LSA from DB summary list. */
2775 ospf_lsdb_delete (lsdb, lsa);
2776 }
2777 }
2778
2779 return length;
2780}
2781
2782int
2783ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2784 unsigned long delta, struct ospf_neighbor *nbr,
2785 struct ospf_lsa *lsa)
2786{
2787 struct ospf_interface *oi;
2788
2789 oi = nbr->oi;
2790
2791 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002792 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002793 return 0;
2794
2795 stream_putl (s, lsa->data->type);
2796 stream_put_ipv4 (s, lsa->data->id.s_addr);
2797 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2798
2799 ospf_lsa_unlock (nbr->ls_req_last);
2800 nbr->ls_req_last = ospf_lsa_lock (lsa);
2801
2802 *length += 12;
2803 return 1;
2804}
2805
2806int
2807ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2808{
2809 struct ospf_lsa *lsa;
2810 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002811 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002812 struct route_table *table;
2813 struct route_node *rn;
2814 int i;
2815 struct ospf_lsdb *lsdb;
2816
2817 lsdb = &nbr->ls_req;
2818
2819 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2820 {
2821 table = lsdb->type[i].db;
2822 for (rn = route_top (table); rn; rn = route_next (rn))
2823 if ((lsa = (rn->info)) != NULL)
2824 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2825 {
2826 route_unlock_node (rn);
2827 break;
2828 }
2829 }
2830 return length;
2831}
2832
2833int
2834ls_age_increment (struct ospf_lsa *lsa, int delay)
2835{
2836 int age;
2837
2838 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2839
2840 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2841}
2842
2843int
hasso52dc7ee2004-09-23 19:18:23 +00002844ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002845{
2846 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002847 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002848 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002849 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002850 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002851 unsigned long pp;
2852 int count = 0;
2853
2854 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002855 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002856
paul9985f832005-02-09 15:51:56 +00002857 pp = stream_get_endp (s);
2858 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002859
gdt86f1fd92005-01-10 14:20:43 +00002860 /* Calculate amount of packet usable for data. */
2861 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2862
paul718e3742002-12-13 20:15:29 +00002863 while ((node = listhead (update)) != NULL)
2864 {
2865 struct lsa_header *lsah;
2866 u_int16_t ls_age;
2867
2868 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002869 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002870
2871 lsa = getdata (node);
2872 assert (lsa);
2873 assert (lsa->data);
2874
paul68b73392004-09-12 14:21:37 +00002875 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002876 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002877 break;
2878
paul718e3742002-12-13 20:15:29 +00002879 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002880 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002881
2882 /* Put LSA to Link State Request. */
2883 stream_put (s, lsa->data, ntohs (lsa->data->length));
2884
2885 /* Set LS age. */
2886 /* each hop must increment an lsa_age by transmit_delay
2887 of OSPF interface */
2888 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2889 lsah->ls_age = htons (ls_age);
2890
2891 length += ntohs (lsa->data->length);
2892 count++;
2893
2894 list_delete_node (update, node);
2895 ospf_lsa_unlock (lsa);
2896 }
2897
2898 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002899 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002900
2901 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002902 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002903 return length;
2904}
2905
2906int
hasso52dc7ee2004-09-23 19:18:23 +00002907ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002908{
hasso52dc7ee2004-09-23 19:18:23 +00002909 struct list *rm_list;
2910 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002911 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002912 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002913 struct ospf_lsa *lsa;
2914
2915 rm_list = list_new ();
2916
2917 for (node = listhead (ack); node; nextnode (node))
2918 {
2919 lsa = getdata (node);
2920 assert (lsa);
2921
gdt86f1fd92005-01-10 14:20:43 +00002922 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002923 break;
2924
2925 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2926 length += OSPF_LSA_HEADER_SIZE;
2927
2928 listnode_add (rm_list, lsa);
2929 }
2930
2931 /* Remove LSA from LS-Ack list. */
2932 for (node = listhead (rm_list); node; nextnode (node))
2933 {
2934 lsa = (struct ospf_lsa *) getdata (node);
2935
2936 listnode_delete (ack, lsa);
2937 ospf_lsa_unlock (lsa);
2938 }
2939
2940 list_delete (rm_list);
2941
2942 return length;
2943}
2944
2945void
2946ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2947{
2948 struct ospf_packet *op;
2949 u_int16_t length = OSPF_HEADER_SIZE;
2950
2951 op = ospf_packet_new (oi->ifp->mtu);
2952
2953 /* Prepare OSPF common header. */
2954 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2955
2956 /* Prepare OSPF Hello body. */
2957 length += ospf_make_hello (oi, op->s);
2958
2959 /* Fill OSPF header. */
2960 ospf_fill_header (oi, op->s, length);
2961
2962 /* Set packet length. */
2963 op->length = length;
2964
2965 op->dst.s_addr = addr->s_addr;
2966
2967 /* Add packet to the interface output queue. */
2968 ospf_packet_add (oi, op);
2969
2970 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002971 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002972}
2973
2974void
2975ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2976{
2977 struct ospf_interface *oi;
2978
2979 oi = nbr_nbma->oi;
2980 assert(oi);
2981
2982 /* If this is passive interface, do not send OSPF Hello. */
2983 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2984 return;
2985
2986 if (oi->type != OSPF_IFTYPE_NBMA)
2987 return;
2988
2989 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2990 return;
2991
2992 if (PRIORITY(oi) == 0)
2993 return;
2994
2995 if (nbr_nbma->priority == 0
2996 && oi->state != ISM_DR && oi->state != ISM_Backup)
2997 return;
2998
2999 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3000}
3001
3002int
3003ospf_poll_timer (struct thread *thread)
3004{
3005 struct ospf_nbr_nbma *nbr_nbma;
3006
3007 nbr_nbma = THREAD_ARG (thread);
3008 nbr_nbma->t_poll = NULL;
3009
3010 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003011 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003012 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3013
3014 ospf_poll_send (nbr_nbma);
3015
3016 if (nbr_nbma->v_poll > 0)
3017 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3018 nbr_nbma->v_poll);
3019
3020 return 0;
3021}
3022
3023
3024int
3025ospf_hello_reply_timer (struct thread *thread)
3026{
3027 struct ospf_neighbor *nbr;
3028
3029 nbr = THREAD_ARG (thread);
3030 nbr->t_hello_reply = NULL;
3031
3032 assert (nbr->oi);
3033
3034 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003035 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003036 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3037
3038 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3039
3040 return 0;
3041}
3042
3043/* Send OSPF Hello. */
3044void
3045ospf_hello_send (struct ospf_interface *oi)
3046{
3047 struct ospf_packet *op;
3048 u_int16_t length = OSPF_HEADER_SIZE;
3049
3050 /* If this is passive interface, do not send OSPF Hello. */
3051 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3052 return;
3053
3054 op = ospf_packet_new (oi->ifp->mtu);
3055
3056 /* Prepare OSPF common header. */
3057 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3058
3059 /* Prepare OSPF Hello body. */
3060 length += ospf_make_hello (oi, op->s);
3061
3062 /* Fill OSPF header. */
3063 ospf_fill_header (oi, op->s, length);
3064
3065 /* Set packet length. */
3066 op->length = length;
3067
3068 if (oi->type == OSPF_IFTYPE_NBMA)
3069 {
3070 struct ospf_neighbor *nbr;
3071 struct route_node *rn;
3072
3073 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3074 if ((nbr = rn->info))
3075 if (nbr != oi->nbr_self)
3076 if (nbr->state != NSM_Down)
3077 {
3078 /* RFC 2328 Section 9.5.1
3079 If the router is not eligible to become Designated Router,
3080 it must periodically send Hello Packets to both the
3081 Designated Router and the Backup Designated Router (if they
3082 exist). */
3083 if (PRIORITY(oi) == 0 &&
3084 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3085 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3086 continue;
3087
3088 /* If the router is eligible to become Designated Router, it
3089 must periodically send Hello Packets to all neighbors that
3090 are also eligible. In addition, if the router is itself the
3091 Designated Router or Backup Designated Router, it must also
3092 send periodic Hello Packets to all other neighbors. */
3093
3094 if (nbr->priority == 0 && oi->state == ISM_DROther)
3095 continue;
3096 /* if oi->state == Waiting, send hello to all neighbors */
3097 {
3098 struct ospf_packet *op_dup;
3099
3100 op_dup = ospf_packet_dup(op);
3101 op_dup->dst = nbr->address.u.prefix4;
3102
3103 /* Add packet to the interface output queue. */
3104 ospf_packet_add (oi, op_dup);
3105
paul020709f2003-04-04 02:44:16 +00003106 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003107 }
3108
3109 }
3110 ospf_packet_free (op);
3111 }
3112 else
3113 {
3114 /* Decide destination address. */
3115 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3116 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3117 else
3118 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3119
3120 /* Add packet to the interface output queue. */
3121 ospf_packet_add (oi, op);
3122
3123 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003124 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003125 }
3126}
3127
3128/* Send OSPF Database Description. */
3129void
3130ospf_db_desc_send (struct ospf_neighbor *nbr)
3131{
3132 struct ospf_interface *oi;
3133 struct ospf_packet *op;
3134 u_int16_t length = OSPF_HEADER_SIZE;
3135
3136 oi = nbr->oi;
3137 op = ospf_packet_new (oi->ifp->mtu);
3138
3139 /* Prepare OSPF common header. */
3140 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3141
3142 /* Prepare OSPF Database Description body. */
3143 length += ospf_make_db_desc (oi, nbr, op->s);
3144
3145 /* Fill OSPF header. */
3146 ospf_fill_header (oi, op->s, length);
3147
3148 /* Set packet length. */
3149 op->length = length;
3150
3151 /* Decide destination address. */
3152 op->dst = nbr->address.u.prefix4;
3153
3154 /* Add packet to the interface output queue. */
3155 ospf_packet_add (oi, op);
3156
3157 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003158 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003159
3160 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3161 if (nbr->last_send)
3162 ospf_packet_free (nbr->last_send);
3163 nbr->last_send = ospf_packet_dup (op);
3164 gettimeofday (&nbr->last_send_ts, NULL);
3165}
3166
3167/* Re-send Database Description. */
3168void
3169ospf_db_desc_resend (struct ospf_neighbor *nbr)
3170{
3171 struct ospf_interface *oi;
3172
3173 oi = nbr->oi;
3174
3175 /* Add packet to the interface output queue. */
3176 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3177
3178 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003179 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003180}
3181
3182/* Send Link State Request. */
3183void
3184ospf_ls_req_send (struct ospf_neighbor *nbr)
3185{
3186 struct ospf_interface *oi;
3187 struct ospf_packet *op;
3188 u_int16_t length = OSPF_HEADER_SIZE;
3189
3190 oi = nbr->oi;
3191 op = ospf_packet_new (oi->ifp->mtu);
3192
3193 /* Prepare OSPF common header. */
3194 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3195
3196 /* Prepare OSPF Link State Request body. */
3197 length += ospf_make_ls_req (nbr, op->s);
3198 if (length == OSPF_HEADER_SIZE)
3199 {
3200 ospf_packet_free (op);
3201 return;
3202 }
3203
3204 /* Fill OSPF header. */
3205 ospf_fill_header (oi, op->s, length);
3206
3207 /* Set packet length. */
3208 op->length = length;
3209
3210 /* Decide destination address. */
3211 op->dst = nbr->address.u.prefix4;
3212
3213 /* Add packet to the interface output queue. */
3214 ospf_packet_add (oi, op);
3215
3216 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003217 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003218
3219 /* Add Link State Request Retransmission Timer. */
3220 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3221}
3222
3223/* Send Link State Update with an LSA. */
3224void
3225ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3226 int flag)
3227{
hasso52dc7ee2004-09-23 19:18:23 +00003228 struct list *update;
paul718e3742002-12-13 20:15:29 +00003229
3230 update = list_new ();
3231
3232 listnode_add (update, lsa);
3233 ospf_ls_upd_send (nbr, update, flag);
3234
3235 list_delete (update);
3236}
3237
paul68b73392004-09-12 14:21:37 +00003238/* Determine size for packet. Must be at least big enough to accomodate next
3239 * LSA on list, which may be bigger than MTU size.
3240 *
3241 * Return pointer to new ospf_packet
3242 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3243 * on packet sizes (in which case offending LSA is deleted from update list)
3244 */
3245static struct ospf_packet *
3246ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3247{
3248 struct ospf_lsa *lsa;
3249 struct listnode *ln;
3250 size_t size;
3251 static char warned = 0;
3252
3253 ln = listhead (update);
3254 lsa = getdata (ln);
3255 assert (lsa);
3256 assert (lsa->data);
3257
3258 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3259 > ospf_packet_max (oi))
3260 {
3261 if (!warned)
3262 {
3263 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3264 "will need to fragment. Not optimal. Try divide up"
3265 " your network with areas. Use 'debug ospf packet send'"
3266 " to see details, or look at 'show ip ospf database ..'");
3267 warned = 1;
3268 }
3269
3270 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003271 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003272 " %d bytes originated by %s, will be fragmented!",
3273 inet_ntoa (lsa->data->id),
3274 ntohs (lsa->data->length),
3275 inet_ntoa (lsa->data->adv_router));
3276
3277 /*
3278 * Allocate just enough to fit this LSA only, to avoid including other
3279 * LSAs in fragmented LSA Updates.
3280 */
3281 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3282 + OSPF_LS_UPD_MIN_SIZE;
3283 }
3284 else
3285 size = oi->ifp->mtu;
3286
gdt86f1fd92005-01-10 14:20:43 +00003287 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003288 if (size > OSPF_MAX_PACKET_SIZE)
3289 {
3290 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003291 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003292 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003293 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003294 (long int) size);
paul68b73392004-09-12 14:21:37 +00003295 list_delete_node (update, ln);
3296 return NULL;
3297 }
3298
3299 return ospf_packet_new (size);
3300}
3301
paul718e3742002-12-13 20:15:29 +00003302static void
hasso52dc7ee2004-09-23 19:18:23 +00003303ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003304 struct in_addr addr)
3305{
3306 struct ospf_packet *op;
3307 u_int16_t length = OSPF_HEADER_SIZE;
3308
3309 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003310 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003311
3312 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003313
3314 /* Prepare OSPF common header. */
3315 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3316
paul59ea14c2004-07-14 20:50:36 +00003317 /* Prepare OSPF Link State Update body.
3318 * Includes Type-7 translation.
3319 */
paul718e3742002-12-13 20:15:29 +00003320 length += ospf_make_ls_upd (oi, update, op->s);
3321
3322 /* Fill OSPF header. */
3323 ospf_fill_header (oi, op->s, length);
3324
3325 /* Set packet length. */
3326 op->length = length;
3327
3328 /* Decide destination address. */
3329 op->dst.s_addr = addr.s_addr;
3330
3331 /* Add packet to the interface output queue. */
3332 ospf_packet_add (oi, op);
3333
3334 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003335 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003336}
3337
3338static int
3339ospf_ls_upd_send_queue_event (struct thread *thread)
3340{
3341 struct ospf_interface *oi = THREAD_ARG(thread);
3342 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003343 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003344 struct list *update;
paul68b73392004-09-12 14:21:37 +00003345 char again = 0;
paul718e3742002-12-13 20:15:29 +00003346
3347 oi->t_ls_upd_event = NULL;
3348
3349 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003350 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003351
paul736d3442003-07-24 23:22:57 +00003352 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003353 {
paul736d3442003-07-24 23:22:57 +00003354 rnext = route_next (rn);
3355
paul718e3742002-12-13 20:15:29 +00003356 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003357 continue;
paul68b73392004-09-12 14:21:37 +00003358
3359 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003360
paul48fe13b2004-07-27 17:40:44 +00003361 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003362
paul68b73392004-09-12 14:21:37 +00003363 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003364 if (listcount(update) == 0)
3365 {
3366 list_delete (rn->info);
3367 rn->info = NULL;
3368 route_unlock_node (rn);
3369 }
3370 else
paul68b73392004-09-12 14:21:37 +00003371 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003372 }
3373
3374 if (again != 0)
3375 {
3376 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003377 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003378 " %d nodes to try again, raising new event", again);
3379 oi->t_ls_upd_event =
3380 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003381 }
3382
3383 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003384 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003385
paul718e3742002-12-13 20:15:29 +00003386 return 0;
3387}
3388
3389void
hasso52dc7ee2004-09-23 19:18:23 +00003390ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003391{
3392 struct ospf_interface *oi;
3393 struct prefix_ipv4 p;
3394 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003395 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003396
3397 oi = nbr->oi;
3398
3399 p.family = AF_INET;
3400 p.prefixlen = IPV4_MAX_BITLEN;
3401
3402 /* Decide destination address. */
3403 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3404 p.prefix = oi->vl_data->peer_addr;
3405 else if (flag == OSPF_SEND_PACKET_DIRECT)
3406 p.prefix = nbr->address.u.prefix4;
3407 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3408 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3409 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3410 && (flag == OSPF_SEND_PACKET_INDIRECT))
3411 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003412 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3413 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003414 else
3415 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3416
3417 if (oi->type == OSPF_IFTYPE_NBMA)
3418 {
3419 if (flag == OSPF_SEND_PACKET_INDIRECT)
3420 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3421 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3422 zlog_warn ("* LS-Update is sent to myself.");
3423 }
3424
3425 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3426
3427 if (rn->info == NULL)
3428 rn->info = list_new ();
3429
3430 for (n = listhead (update); n; nextnode (n))
3431 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3432
3433 if (oi->t_ls_upd_event == NULL)
3434 oi->t_ls_upd_event =
3435 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3436}
3437
3438static void
hasso52dc7ee2004-09-23 19:18:23 +00003439ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3440 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003441{
3442 struct ospf_packet *op;
3443 u_int16_t length = OSPF_HEADER_SIZE;
3444
3445 op = ospf_packet_new (oi->ifp->mtu);
3446
3447 /* Prepare OSPF common header. */
3448 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3449
3450 /* Prepare OSPF Link State Acknowledgment body. */
3451 length += ospf_make_ls_ack (oi, ack, op->s);
3452
3453 /* Fill OSPF header. */
3454 ospf_fill_header (oi, op->s, length);
3455
3456 /* Set packet length. */
3457 op->length = length;
3458
3459 /* Set destination IP address. */
3460 op->dst = dst;
3461
3462 /* Add packet to the interface output queue. */
3463 ospf_packet_add (oi, op);
3464
3465 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003466 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003467}
3468
3469static int
3470ospf_ls_ack_send_event (struct thread *thread)
3471{
3472 struct ospf_interface *oi = THREAD_ARG (thread);
3473
3474 oi->t_ls_ack_direct = NULL;
3475
3476 while (listcount (oi->ls_ack_direct.ls_ack))
3477 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3478 oi->ls_ack_direct.dst);
3479
3480 return 0;
3481}
3482
3483void
3484ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3485{
3486 struct ospf_interface *oi = nbr->oi;
3487
3488 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3489 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3490
3491 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3492
3493 if (oi->t_ls_ack_direct == NULL)
3494 oi->t_ls_ack_direct =
3495 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3496}
3497
3498/* Send Link State Acknowledgment delayed. */
3499void
3500ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3501{
3502 struct in_addr dst;
3503
3504 /* Decide destination address. */
3505 /* RFC2328 Section 13.5 On non-broadcast
3506 networks, delayed Link State Acknowledgment packets must be
3507 unicast separately over each adjacency (i.e., neighbor whose
3508 state is >= Exchange). */
3509 if (oi->type == OSPF_IFTYPE_NBMA)
3510 {
3511 struct ospf_neighbor *nbr;
3512 struct route_node *rn;
3513
3514 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3515 if ((nbr = rn->info) != NULL)
3516 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3517 while (listcount (oi->ls_ack))
3518 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3519 return;
3520 }
3521 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3522 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3523 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3524 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3525 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3526 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003527 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3528 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003529 else
3530 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3531
3532 while (listcount (oi->ls_ack))
3533 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3534}