blob: 038fd657572de4630921614b89a7c5a151865a76 [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
217struct stream *
218ospf_stream_copy (struct stream *new, struct stream *s)
219{
220 new->endp = s->endp;
paul718e3742002-12-13 20:15:29 +0000221 new->getp = s->getp;
222
223 memcpy (new->data, s->data, stream_get_endp (s));
224
225 return new;
226}
227
228struct ospf_packet *
229ospf_packet_dup (struct ospf_packet *op)
230{
231 struct ospf_packet *new;
232
paul37163d62003-02-03 18:40:56 +0000233 if (stream_get_endp(op->s) != op->length)
234 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000235 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000236
237 /* Reserve space for MD5 authentication that may be added later. */
238 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000239 ospf_stream_copy (new->s, op->s);
240
241 new->dst = op->dst;
242 new->length = op->length;
243
244 return new;
245}
246
gdt86f1fd92005-01-10 14:20:43 +0000247/* XXX inline */
248unsigned int
249ospf_packet_authspace (struct ospf_interface *oi)
250{
251 int auth = 0;
252
253 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
254 auth = OSPF_AUTH_MD5_SIZE;
255
256 return auth;
257}
258
paul6c835672004-10-11 11:00:30 +0000259unsigned int
paul718e3742002-12-13 20:15:29 +0000260ospf_packet_max (struct ospf_interface *oi)
261{
262 int max;
263
gdt86f1fd92005-01-10 14:20:43 +0000264 max = oi->ifp->mtu - ospf_packet_authspace(oi);
265
paul68b73392004-09-12 14:21:37 +0000266 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000267
268 return max;
269}
270
271
272int
273ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
274 u_int16_t length)
275{
paul6c835672004-10-11 11:00:30 +0000276 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000277 struct md5_ctx ctx;
278 unsigned char digest[OSPF_AUTH_MD5_SIZE];
279 unsigned char *pdigest;
280 struct crypt_key *ck;
281 struct ospf_header *ospfh;
282 struct ospf_neighbor *nbr;
283
284
285 ibuf = STREAM_PNT (s);
286 ospfh = (struct ospf_header *) ibuf;
287
288 /* Get pointer to the end of the packet. */
289 pdigest = ibuf + length;
290
291 /* Get secret key. */
292 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
293 ospfh->u.crypt.key_id);
294 if (ck == NULL)
295 {
296 zlog_warn ("interface %s: ospf_check_md5 no key %d",
297 IF_NAME (oi), ospfh->u.crypt.key_id);
298 return 0;
299 }
300
301 /* check crypto seqnum. */
302 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
303
304 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
305 {
306 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
307 IF_NAME (oi),
308 ntohl(ospfh->u.crypt.crypt_seqnum),
309 ntohl(nbr->crypt_seqnum));
310 return 0;
311 }
312
313 /* Generate a digest for the ospf packet - their digest + our digest. */
314 md5_init_ctx (&ctx);
315 md5_process_bytes (ibuf, length, &ctx);
316 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
317 md5_finish_ctx (&ctx, digest);
318
319 /* compare the two */
320 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
321 {
322 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
323 IF_NAME (oi));
324 return 0;
325 }
326
327 /* save neighbor's crypt_seqnum */
328 if (nbr)
329 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
330 return 1;
331}
332
333/* This function is called from ospf_write(), it will detect the
334 authentication scheme and if it is MD5, it will change the sequence
335 and update the MD5 digest. */
336int
337ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
338{
339 struct ospf_header *ospfh;
340 unsigned char digest[OSPF_AUTH_MD5_SIZE];
341 struct md5_ctx ctx;
342 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000343 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000344 struct crypt_key *ck;
345 char *auth_key;
346
347 ibuf = STREAM_DATA (op->s);
348 ospfh = (struct ospf_header *) ibuf;
349
350 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
351 return 0;
352
353 /* We do this here so when we dup a packet, we don't have to
354 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000355 t = (time(NULL) & 0xFFFFFFFF);
356 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
357 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000358
359 /* Get MD5 Authentication key from auth_key list. */
360 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000361 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000362 else
363 {
364 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000365 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000366 }
367
368 /* Generate a digest for the entire packet + our secret key. */
369 md5_init_ctx (&ctx);
370 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
371 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
372 md5_finish_ctx (&ctx, digest);
373
374 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000375 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000376
377 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000378 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
379
paul37163d62003-02-03 18:40:56 +0000380 if (stream_get_endp(op->s) != op->length)
381 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 +0000382
383 return OSPF_AUTH_MD5_SIZE;
384}
385
386
387int
388ospf_ls_req_timer (struct thread *thread)
389{
390 struct ospf_neighbor *nbr;
391
392 nbr = THREAD_ARG (thread);
393 nbr->t_ls_req = NULL;
394
395 /* Send Link State Request. */
396 if (ospf_ls_request_count (nbr))
397 ospf_ls_req_send (nbr);
398
399 /* Set Link State Request retransmission timer. */
400 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
401
402 return 0;
403}
404
405void
406ospf_ls_req_event (struct ospf_neighbor *nbr)
407{
408 if (nbr->t_ls_req)
409 {
410 thread_cancel (nbr->t_ls_req);
411 nbr->t_ls_req = NULL;
412 }
413 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
414}
415
416/* Cyclic timer function. Fist registered in ospf_nbr_new () in
417 ospf_neighbor.c */
418int
419ospf_ls_upd_timer (struct thread *thread)
420{
421 struct ospf_neighbor *nbr;
422
423 nbr = THREAD_ARG (thread);
424 nbr->t_ls_upd = NULL;
425
426 /* Send Link State Update. */
427 if (ospf_ls_retransmit_count (nbr) > 0)
428 {
hasso52dc7ee2004-09-23 19:18:23 +0000429 struct list *update;
paul718e3742002-12-13 20:15:29 +0000430 struct ospf_lsdb *lsdb;
431 int i;
432 struct timeval now;
433 int retransmit_interval;
434
435 gettimeofday (&now, NULL);
436 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
437
438 lsdb = &nbr->ls_rxmt;
439 update = list_new ();
440
441 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
442 {
443 struct route_table *table = lsdb->type[i].db;
444 struct route_node *rn;
445
446 for (rn = route_top (table); rn; rn = route_next (rn))
447 {
448 struct ospf_lsa *lsa;
449
450 if ((lsa = rn->info) != NULL)
451 /* Don't retransmit an LSA if we received it within
452 the last RxmtInterval seconds - this is to allow the
453 neighbour a chance to acknowledge the LSA as it may
454 have ben just received before the retransmit timer
455 fired. This is a small tweak to what is in the RFC,
456 but it will cut out out a lot of retransmit traffic
457 - MAG */
458 if (tv_cmp (tv_sub (now, lsa->tv_recv),
459 int2tv (retransmit_interval)) >= 0)
460 listnode_add (update, rn->info);
461 }
462 }
463
464 if (listcount (update) > 0)
465 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
466 list_delete (update);
467 }
468
469 /* Set LS Update retransmission timer. */
470 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
471
472 return 0;
473}
474
475int
476ospf_ls_ack_timer (struct thread *thread)
477{
478 struct ospf_interface *oi;
479
480 oi = THREAD_ARG (thread);
481 oi->t_ls_ack = NULL;
482
483 /* Send Link State Acknowledgment. */
484 if (listcount (oi->ls_ack) > 0)
485 ospf_ls_ack_send_delayed (oi);
486
487 /* Set LS Ack timer. */
488 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
489
490 return 0;
491}
492
paul0bfeca32004-09-24 08:07:54 +0000493#ifdef WANT_OSPF_WRITE_FRAGMENT
494void
paul6a99f832004-09-27 12:56:30 +0000495ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000496 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000497 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000498{
499#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000500 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000501 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000502 int ret;
paul0bfeca32004-09-24 08:07:54 +0000503
504 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000505 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000506
507 /* we can but try.
508 *
509 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
510 * well as the IP_MF flag, making this all quite pointless.
511 *
512 * However, for a system on which IP_MF is left alone, and ip_id left
513 * alone or else which sets same ip_id for each fragment this might
514 * work, eg linux.
515 *
516 * XXX-TODO: It would be much nicer to have the kernel's use their
517 * existing fragmentation support to do this for us. Bugs/RFEs need to
518 * be raised against the various kernels.
519 */
520
521 /* set More Frag */
522 iph->ip_off |= IP_MF;
523
524 /* ip frag offset is expressed in units of 8byte words */
525 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
526
paul62d8e962004-11-02 20:26:45 +0000527 iovp = &msg->msg_iov[1];
528
paul0bfeca32004-09-24 08:07:54 +0000529 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
530 > maxdatasize )
531 {
532 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000533 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
534 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000535 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000536
paul18b12c32004-10-05 14:38:29 +0000537 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000538
paul6a99f832004-09-27 12:56:30 +0000539 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000540
paul18b12c32004-10-05 14:38:29 +0000541 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000542
543 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000544 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000545 " id %d, off %d, len %d failed with %s",
546 inet_ntoa (iph->ip_dst),
547 iph->ip_id,
548 iph->ip_off,
549 iph->ip_len,
ajs6099b3b2004-11-20 02:06:59 +0000550 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000551
paul37ccfa32004-10-31 11:24:51 +0000552 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
553 {
ajs2a42e282004-12-08 18:43:03 +0000554 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000555 iph->ip_id, iph->ip_off, iph->ip_len,
556 inet_ntoa (iph->ip_dst));
557 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
558 {
ajs2a42e282004-12-08 18:43:03 +0000559 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000560 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000561 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000562 }
563 }
564
paul0bfeca32004-09-24 08:07:54 +0000565 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000566 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000567 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000568 }
569
570 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000571 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
572 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000573 iph->ip_off &= (~IP_MF);
574}
575#endif /* WANT_OSPF_WRITE_FRAGMENT */
576
paul718e3742002-12-13 20:15:29 +0000577int
578ospf_write (struct thread *thread)
579{
paul68980082003-03-25 05:07:42 +0000580 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000581 struct ospf_interface *oi;
582 struct ospf_packet *op;
583 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000584 struct ip iph;
585 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000586 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000587 u_char type;
588 int ret;
589 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000590 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000591#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000592 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000593#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000594 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000595#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000596
paul68980082003-03-25 05:07:42 +0000597 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000598
paul68980082003-03-25 05:07:42 +0000599 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000600 assert (node);
601 oi = getdata (node);
602 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000603
604#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000605 /* seed ipid static with low order bits of time */
606 if (ipid == 0)
607 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000608#endif /* WANT_OSPF_WRITE_FRAGMENT */
609
paul68b73392004-09-12 14:21:37 +0000610 /* convenience - max OSPF data per packet */
611 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
612
paul718e3742002-12-13 20:15:29 +0000613 /* Get one packet from queue. */
614 op = ospf_fifo_head (oi->obuf);
615 assert (op);
616 assert (op->length >= OSPF_HEADER_SIZE);
617
paul68980082003-03-25 05:07:42 +0000618 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
619 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000620 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
621
paul718e3742002-12-13 20:15:29 +0000622 /* Rewrite the md5 signature & update the seq */
623 ospf_make_md5_digest (oi, op);
624
paul37ccfa32004-10-31 11:24:51 +0000625 /* Retrieve OSPF packet type. */
626 stream_set_getp (op->s, 1);
627 type = stream_getc (op->s);
628
paul68b73392004-09-12 14:21:37 +0000629 /* reset get pointer */
630 stream_set_getp (op->s, 0);
631
632 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000633 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000634
paul718e3742002-12-13 20:15:29 +0000635 sa_dst.sin_family = AF_INET;
636#ifdef HAVE_SIN_LEN
637 sa_dst.sin_len = sizeof(sa_dst);
638#endif /* HAVE_SIN_LEN */
639 sa_dst.sin_addr = op->dst;
640 sa_dst.sin_port = htons (0);
641
642 /* Set DONTROUTE flag if dst is unicast. */
643 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
644 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
645 flags = MSG_DONTROUTE;
646
paul68b73392004-09-12 14:21:37 +0000647 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
648 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000649 if ( sizeof (struct ip)
650 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000651 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
652
paul718e3742002-12-13 20:15:29 +0000653 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000654 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000655 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000656
paul0bfeca32004-09-24 08:07:54 +0000657#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000658 /* XXX-MT: not thread-safe at all..
659 * XXX: this presumes this is only programme sending OSPF packets
660 * otherwise, no guarantee ipid will be unique
661 */
662 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000663#endif /* WANT_OSPF_WRITE_FRAGMENT */
664
paul718e3742002-12-13 20:15:29 +0000665 iph.ip_off = 0;
666 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
667 iph.ip_ttl = OSPF_VL_IP_TTL;
668 else
669 iph.ip_ttl = OSPF_IP_TTL;
670 iph.ip_p = IPPROTO_OSPFIGP;
671 iph.ip_sum = 0;
672 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
673 iph.ip_dst.s_addr = op->dst.s_addr;
674
675 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000676 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000677 msg.msg_namelen = sizeof (sa_dst);
678 msg.msg_iov = iov;
679 msg.msg_iovlen = 2;
680 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000681 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
682 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000683 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000684
685 /* Sadly we can not rely on kernels to fragment packets because of either
686 * IP_HDRINCL and/or multicast destination being set.
687 */
paul0bfeca32004-09-24 08:07:54 +0000688#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000689 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000690 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
691 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000692#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000693
694 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000695 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000696 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000697 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000698
699 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000700 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
701 "id %d, off %d, len %d: %s",
702 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
703 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000704
paul718e3742002-12-13 20:15:29 +0000705 /* Show debug sending packet. */
706 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
707 {
708 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
709 {
ajs2a42e282004-12-08 18:43:03 +0000710 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000711 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000712 stream_set_getp (op->s, 0);
713 ospf_packet_dump (op->s);
714 }
715
ajs2a42e282004-12-08 18:43:03 +0000716 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000717 ospf_packet_type_str[type], inet_ntoa (op->dst),
718 IF_NAME (oi));
719
720 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000721 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000722 }
723
724 /* Now delete packet from queue. */
725 ospf_packet_delete (oi);
726
727 if (ospf_fifo_head (oi->obuf) == NULL)
728 {
729 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000730 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000731 }
732
733 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000734 if (!list_isempty (ospf->oi_write_q))
735 ospf->t_write =
736 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000737
738 return 0;
739}
740
741/* OSPF Hello message read -- RFC2328 Section 10.5. */
742void
743ospf_hello (struct ip *iph, struct ospf_header *ospfh,
744 struct stream * s, struct ospf_interface *oi, int size)
745{
746 struct ospf_hello *hello;
747 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000748 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000749 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000750
751 /* increment statistics. */
752 oi->hello_in++;
753
754 hello = (struct ospf_hello *) STREAM_PNT (s);
755
756 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000757 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000758 {
759 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
760 {
ajs2a42e282004-12-08 18:43:03 +0000761 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000762 "dropping.",
763 ospf_packet_type_str[ospfh->type],
764 inet_ntoa (iph->ip_src));
765 }
766 return;
767 }
paul718e3742002-12-13 20:15:29 +0000768
769 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000770 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000771 char buf[3][INET_ADDRSTRLEN];
772 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
773 "should not receive hellos on passive interface %s!",
774 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
775 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
776 inet_ntop(AF_INET, &oi->address->u.prefix4,
777 buf[2], sizeof(buf[2])));
778 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
779 {
780 /* Try to fix multicast membership. */
781 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
782 ospf_if_set_multicast(oi);
783 }
paul718e3742002-12-13 20:15:29 +0000784 return;
paulf2c80652002-12-13 21:44:27 +0000785 }
paul718e3742002-12-13 20:15:29 +0000786
787 /* get neighbor prefix. */
788 p.family = AF_INET;
789 p.prefixlen = ip_masklen (hello->network_mask);
790 p.u.prefix4 = iph->ip_src;
791
792 /* Compare network mask. */
793 /* Checking is ignored for Point-to-Point and Virtual link. */
794 if (oi->type != OSPF_IFTYPE_POINTOPOINT
795 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
796 if (oi->address->prefixlen != p.prefixlen)
797 {
798 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
799 inet_ntoa (ospfh->router_id));
800 return;
801 }
802
803 /* Compare Hello Interval. */
804 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
805 {
806 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
807 inet_ntoa (ospfh->router_id));
808 return;
809 }
810
811 /* Compare Router Dead Interval. */
812 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
813 {
814 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
815 inet_ntoa (ospfh->router_id));
816 return;
817 }
818
819 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000820 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000821 inet_ntoa (ospfh->router_id),
822 ospf_options_dump (hello->options));
823
824 /* Compare options. */
825#define REJECT_IF_TBIT_ON 1 /* XXX */
826#ifdef REJECT_IF_TBIT_ON
827 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
828 {
829 /*
830 * This router does not support non-zero TOS.
831 * Drop this Hello packet not to establish neighbor relationship.
832 */
833 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
834 inet_ntoa (ospfh->router_id));
835 return;
836 }
837#endif /* REJECT_IF_TBIT_ON */
838
839#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000840 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000841 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
842 {
843 /*
844 * This router does know the correct usage of O-bit
845 * the bit should be set in DD packet only.
846 */
847 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
848 inet_ntoa (ospfh->router_id));
849#ifdef STRICT_OBIT_USAGE_CHECK
850 return; /* Reject this packet. */
851#else /* STRICT_OBIT_USAGE_CHECK */
852 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
853#endif /* STRICT_OBIT_USAGE_CHECK */
854 }
855#endif /* HAVE_OPAQUE_LSA */
856
857 /* new for NSSA is to ensure that NP is on and E is off */
858
paul718e3742002-12-13 20:15:29 +0000859 if (oi->area->external_routing == OSPF_AREA_NSSA)
860 {
861 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
862 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
863 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
864 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
865 {
866 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
867 return;
868 }
869 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000870 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000871 }
872 else
paul718e3742002-12-13 20:15:29 +0000873 /* The setting of the E-bit found in the Hello Packet's Options
874 field must match this area's ExternalRoutingCapability A
875 mismatch causes processing to stop and the packet to be
876 dropped. The setting of the rest of the bits in the Hello
877 Packet's Options field should be ignored. */
878 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
879 CHECK_FLAG (hello->options, OSPF_OPTION_E))
880 {
ajs3aa8d5f2004-12-11 18:00:06 +0000881 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
882 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000883 return;
884 }
paul718e3742002-12-13 20:15:29 +0000885
pauld3f0d622004-05-05 15:27:15 +0000886 /* get neighbour struct */
887 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
888
889 /* neighbour must be valid, ospf_nbr_get creates if none existed */
890 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000891
892 old_state = nbr->state;
893
894 /* Add event to thread. */
895 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
896
897 /* RFC2328 Section 9.5.1
898 If the router is not eligible to become Designated Router,
899 (snip) It must also send an Hello Packet in reply to an
900 Hello Packet received from any eligible neighbor (other than
901 the current Designated Router and Backup Designated Router). */
902 if (oi->type == OSPF_IFTYPE_NBMA)
903 if (PRIORITY(oi) == 0 && hello->priority > 0
904 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
905 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
906 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
907 OSPF_HELLO_REPLY_DELAY);
908
909 /* on NBMA network type, it happens to receive bidirectional Hello packet
910 without advance 1-Way Received event.
911 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
912 if (oi->type == OSPF_IFTYPE_NBMA &&
913 (old_state == NSM_Down || old_state == NSM_Attempt))
914 {
915 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
916 nbr->priority = hello->priority;
917 nbr->d_router = hello->d_router;
918 nbr->bd_router = hello->bd_router;
919 return;
920 }
921
paul68980082003-03-25 05:07:42 +0000922 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000923 size - OSPF_HELLO_MIN_SIZE))
924 {
925 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
926 nbr->options |= hello->options;
927 }
928 else
929 {
930 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
931 /* Set neighbor information. */
932 nbr->priority = hello->priority;
933 nbr->d_router = hello->d_router;
934 nbr->bd_router = hello->bd_router;
935 return;
936 }
937
938 /* If neighbor itself declares DR and no BDR exists,
939 cause event BackupSeen */
940 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
941 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
942 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
943
944 /* neighbor itself declares BDR. */
945 if (oi->state == ISM_Waiting &&
946 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
947 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
948
949 /* had not previously. */
950 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
951 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
952 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
953 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
955
956 /* had not previously. */
957 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
958 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
959 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
960 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
961 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
962
963 /* Neighbor priority check. */
964 if (nbr->priority >= 0 && nbr->priority != hello->priority)
965 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
966
967 /* Set neighbor information. */
968 nbr->priority = hello->priority;
969 nbr->d_router = hello->d_router;
970 nbr->bd_router = hello->bd_router;
971}
972
973/* Save DD flags/options/Seqnum received. */
974void
975ospf_db_desc_save_current (struct ospf_neighbor *nbr,
976 struct ospf_db_desc *dd)
977{
978 nbr->last_recv.flags = dd->flags;
979 nbr->last_recv.options = dd->options;
980 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
981}
982
983/* Process rest of DD packet. */
984static void
985ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
986 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
987 u_int16_t size)
988{
989 struct ospf_lsa *new, *find;
990 struct lsa_header *lsah;
991
paul9985f832005-02-09 15:51:56 +0000992 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000993 for (size -= OSPF_DB_DESC_MIN_SIZE;
994 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
995 {
996 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000997 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000998
999 /* Unknown LS type. */
1000 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1001 {
ajsbec595a2004-11-30 22:38:43 +00001002 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001003 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1004 return;
1005 }
1006
1007#ifdef HAVE_OPAQUE_LSA
1008 if (IS_OPAQUE_LSA (lsah->type)
1009 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1010 {
1011 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1012 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1013 return;
1014 }
1015#endif /* HAVE_OPAQUE_LSA */
1016
1017 switch (lsah->type)
1018 {
1019 case OSPF_AS_EXTERNAL_LSA:
1020#ifdef HAVE_OPAQUE_LSA
1021 case OSPF_OPAQUE_AS_LSA:
1022#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001023 /* Check for stub area. Reject if AS-External from stub but
1024 allow if from NSSA. */
1025 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001026 {
1027 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1028 lsah->type, inet_ntoa (lsah->id),
1029 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1030 "STUB" : "NSSA");
1031 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1032 return;
1033 }
1034 break;
1035 default:
1036 break;
1037 }
1038
1039 /* Create LS-request object. */
1040 new = ospf_ls_request_new (lsah);
1041
1042 /* Lookup received LSA, then add LS request list. */
1043 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1044 if (!find || ospf_lsa_more_recent (find, new) < 0)
1045 {
1046 ospf_ls_request_add (nbr, new);
1047 ospf_lsa_discard (new);
1048 }
1049 else
1050 {
1051 /* Received LSA is not recent. */
1052 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001053 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001054 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1055 ospf_lsa_discard (new);
1056 continue;
1057 }
1058 }
1059
1060 /* Master */
1061 if (IS_SET_DD_MS (nbr->dd_flags))
1062 {
1063 nbr->dd_seqnum++;
1064 /* Entire DD packet sent. */
1065 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1066 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1067 else
1068 /* Send new DD packet. */
1069 ospf_db_desc_send (nbr);
1070 }
1071 /* Slave */
1072 else
1073 {
1074 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1075
1076 /* When master's more flags is not set. */
1077 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1078 {
1079 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1080 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1081 }
1082
ajsbec595a2004-11-30 22:38:43 +00001083 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001084 ospf_db_desc_send (nbr);
1085 }
1086
1087 /* Save received neighbor values from DD. */
1088 ospf_db_desc_save_current (nbr, dd);
1089}
1090
1091int
1092ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1093{
1094 /* Is DD duplicated? */
1095 if (dd->options == nbr->last_recv.options &&
1096 dd->flags == nbr->last_recv.flags &&
1097 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1098 return 1;
1099
1100 return 0;
1101}
1102
1103/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001104static void
paul718e3742002-12-13 20:15:29 +00001105ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1106 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1107{
1108 struct ospf_db_desc *dd;
1109 struct ospf_neighbor *nbr;
1110
1111 /* Increment statistics. */
1112 oi->db_desc_in++;
1113
1114 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001115
pauld3f0d622004-05-05 15:27:15 +00001116 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001117 if (nbr == NULL)
1118 {
1119 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1120 inet_ntoa (ospfh->router_id));
1121 return;
1122 }
1123
1124 /* Check MTU. */
1125 if (ntohs (dd->mtu) > oi->ifp->mtu)
1126 {
ajs3aa8d5f2004-12-11 18:00:06 +00001127 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1128 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1129 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001130 return;
1131 }
1132
pauld363df22003-06-19 00:26:34 +00001133 /*
1134 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1135 * required. In fact at least JunOS sends DD packets with P bit clear.
1136 * Until proper solution is developped, this hack should help.
1137 *
1138 * Update: According to the RFCs, N bit is specified /only/ for Hello
1139 * options, unfortunately its use in DD options is not specified. Hence some
1140 * implementations follow E-bit semantics and set it in DD options, and some
1141 * treat it as unspecified and hence follow the directive "default for
1142 * options is clear", ie unset.
1143 *
1144 * Reset the flag, as ospfd follows E-bit semantics.
1145 */
1146 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1147 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1148 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1149 {
1150 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001151 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001152 inet_ntoa (nbr->router_id) );
1153 SET_FLAG (dd->options, OSPF_OPTION_NP);
1154 }
pauld363df22003-06-19 00:26:34 +00001155
paul718e3742002-12-13 20:15:29 +00001156#ifdef REJECT_IF_TBIT_ON
1157 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1158 {
1159 /*
1160 * In Hello protocol, optional capability must have checked
1161 * to prevent this T-bit enabled router be my neighbor.
1162 */
1163 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1164 return;
1165 }
1166#endif /* REJECT_IF_TBIT_ON */
1167
1168#ifdef HAVE_OPAQUE_LSA
1169 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001170 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001171 {
1172 /*
1173 * This node is not configured to handle O-bit, for now.
1174 * Clear it to ignore unsupported capability proposed by neighbor.
1175 */
1176 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1177 }
1178#endif /* HAVE_OPAQUE_LSA */
1179
1180 /* Process DD packet by neighbor status. */
1181 switch (nbr->state)
1182 {
1183 case NSM_Down:
1184 case NSM_Attempt:
1185 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001186 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001187 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001188 LOOKUP (ospf_nsm_state_msg, nbr->state));
1189 break;
1190 case NSM_Init:
1191 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1192 /* If the new state is ExStart, the processing of the current
1193 packet should then continue in this new state by falling
1194 through to case ExStart below. */
1195 if (nbr->state != NSM_ExStart)
1196 break;
1197 case NSM_ExStart:
1198 /* Initial DBD */
1199 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1200 (size == OSPF_DB_DESC_MIN_SIZE))
1201 {
paul68980082003-03-25 05:07:42 +00001202 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001203 {
1204 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001205 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001206 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001207 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1208 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1209 }
1210 else
1211 {
1212 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001213 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1214 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001215 break;
1216 }
1217 }
1218 /* Ack from the Slave */
1219 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1220 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001221 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001222 {
ajs17eaa722004-12-29 21:04:48 +00001223 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001224 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001225 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1226 }
1227 else
1228 {
ajs3aa8d5f2004-12-11 18:00:06 +00001229 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1230 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001231 break;
1232 }
1233
1234 /* This is where the real Options are saved */
1235 nbr->options = dd->options;
1236
1237#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001238 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001239 {
1240 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001241 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001242 inet_ntoa (nbr->router_id),
1243 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1244
1245 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1246 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1247 {
1248 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1249 /* This situation is undesirable, but not a real error. */
1250 }
1251 }
1252#endif /* HAVE_OPAQUE_LSA */
1253
1254 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1255
1256 /* continue processing rest of packet. */
1257 ospf_db_desc_proc (s, oi, nbr, dd, size);
1258 break;
1259 case NSM_Exchange:
1260 if (ospf_db_desc_is_dup (dd, nbr))
1261 {
1262 if (IS_SET_DD_MS (nbr->dd_flags))
1263 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001264 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1265 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001266 else
1267 /* Slave: cause to retransmit the last Database Description. */
1268 {
ajs3aa8d5f2004-12-11 18:00:06 +00001269 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1270 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001271 ospf_db_desc_resend (nbr);
1272 }
1273 break;
1274 }
1275
1276 /* Otherwise DD packet should be checked. */
1277 /* Check Master/Slave bit mismatch */
1278 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1279 {
ajs3aa8d5f2004-12-11 18:00:06 +00001280 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1281 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001282 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1283 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001284 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001285 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001286 break;
1287 }
1288
1289 /* Check initialize bit is set. */
1290 if (IS_SET_DD_I (dd->flags))
1291 {
ajs3aa8d5f2004-12-11 18:00:06 +00001292 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1293 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001294 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1295 break;
1296 }
1297
1298 /* Check DD Options. */
1299 if (dd->options != nbr->options)
1300 {
1301#ifdef ORIGINAL_CODING
1302 /* Save the new options for debugging */
1303 nbr->options = dd->options;
1304#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001305 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1306 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001307 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1308 break;
1309 }
1310
1311 /* Check DD sequence number. */
1312 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1313 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1314 (!IS_SET_DD_MS (nbr->dd_flags) &&
1315 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1316 {
ajs3aa8d5f2004-12-11 18:00:06 +00001317 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1318 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001319 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1320 break;
1321 }
1322
1323 /* Continue processing rest of packet. */
1324 ospf_db_desc_proc (s, oi, nbr, dd, size);
1325 break;
1326 case NSM_Loading:
1327 case NSM_Full:
1328 if (ospf_db_desc_is_dup (dd, nbr))
1329 {
1330 if (IS_SET_DD_MS (nbr->dd_flags))
1331 {
1332 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001333 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1334 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001335 break;
1336 }
1337 else
1338 {
1339 struct timeval t, now;
1340 gettimeofday (&now, NULL);
1341 t = tv_sub (now, nbr->last_send_ts);
1342 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1343 {
1344 /* In states Loading and Full the slave must resend
1345 its last Database Description packet in response to
1346 duplicate Database Description packets received
1347 from the master. For this reason the slave must
1348 wait RouterDeadInterval seconds before freeing the
1349 last Database Description packet. Reception of a
1350 Database Description packet from the master after
1351 this interval will generate a SeqNumberMismatch
1352 neighbor event. RFC2328 Section 10.8 */
1353 ospf_db_desc_resend (nbr);
1354 break;
1355 }
1356 }
1357 }
1358
1359 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1360 break;
1361 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001362 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1363 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001364 break;
1365 }
1366}
1367
1368#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1369
1370/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1371void
1372ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1373 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1374{
1375 struct ospf_neighbor *nbr;
1376 u_int32_t ls_type;
1377 struct in_addr ls_id;
1378 struct in_addr adv_router;
1379 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001380 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001381 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001382
1383 /* Increment statistics. */
1384 oi->ls_req_in++;
1385
pauld3f0d622004-05-05 15:27:15 +00001386 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001387 if (nbr == NULL)
1388 {
1389 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1390 inet_ntoa (ospfh->router_id));
1391 return;
1392 }
1393
1394 /* Neighbor State should be Exchange or later. */
1395 if (nbr->state != NSM_Exchange &&
1396 nbr->state != NSM_Loading &&
1397 nbr->state != NSM_Full)
1398 {
ajsbec595a2004-11-30 22:38:43 +00001399 zlog_warn ("Link State Request received from %s: "
1400 "Neighbor state is %s, packet discarded.",
1401 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001402 LOOKUP (ospf_nsm_state_msg, nbr->state));
1403 return;
1404 }
1405
1406 /* Send Link State Update for ALL requested LSAs. */
1407 ls_upd = list_new ();
1408 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1409
1410 while (size >= OSPF_LSA_KEY_SIZE)
1411 {
1412 /* Get one slice of Link State Request. */
1413 ls_type = stream_getl (s);
1414 ls_id.s_addr = stream_get_ipv4 (s);
1415 adv_router.s_addr = stream_get_ipv4 (s);
1416
1417 /* Verify LSA type. */
1418 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1419 {
1420 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1421 list_delete (ls_upd);
1422 return;
1423 }
1424
1425 /* Search proper LSA in LSDB. */
1426 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1427 if (find == NULL)
1428 {
1429 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1430 list_delete (ls_upd);
1431 return;
1432 }
1433
gdt86f1fd92005-01-10 14:20:43 +00001434 /* Packet overflows MTU size, send immediately. */
1435 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001436 {
1437 if (oi->type == OSPF_IFTYPE_NBMA)
1438 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1439 else
1440 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1441
1442 /* Only remove list contents. Keep ls_upd. */
1443 list_delete_all_node (ls_upd);
1444
1445 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1446 }
1447
1448 /* Append LSA to update list. */
1449 listnode_add (ls_upd, find);
1450 length += ntohs (find->data->length);
1451
1452 size -= OSPF_LSA_KEY_SIZE;
1453 }
1454
1455 /* Send rest of Link State Update. */
1456 if (listcount (ls_upd) > 0)
1457 {
1458 if (oi->type == OSPF_IFTYPE_NBMA)
1459 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1460 else
1461 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1462
1463 list_delete (ls_upd);
1464 }
1465 else
1466 list_free (ls_upd);
1467}
1468
1469/* Get the list of LSAs from Link State Update packet.
1470 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001471static struct list *
paul718e3742002-12-13 20:15:29 +00001472ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1473 struct ospf_interface *oi, size_t size)
1474{
1475 u_int16_t count, sum;
1476 u_int32_t length;
1477 struct lsa_header *lsah;
1478 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001479 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001480
1481 lsas = list_new ();
1482
1483 count = stream_getl (s);
1484 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1485
1486 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001487 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001488 {
1489 lsah = (struct lsa_header *) STREAM_PNT (s);
1490 length = ntohs (lsah->length);
1491
1492 if (length > size)
1493 {
1494 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1495 break;
1496 }
1497
1498 /* Validate the LSA's LS checksum. */
1499 sum = lsah->checksum;
1500 if (sum != ospf_lsa_checksum (lsah))
1501 {
1502 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1503 sum, lsah->checksum);
1504 continue;
1505 }
1506
1507 /* Examine the LSA's LS type. */
1508 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1509 {
1510 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1511 continue;
1512 }
1513
1514 /*
1515 * What if the received LSA's age is greater than MaxAge?
1516 * Treat it as a MaxAge case -- endo.
1517 */
1518 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1519 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1520
1521#ifdef HAVE_OPAQUE_LSA
1522 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1523 {
1524#ifdef STRICT_OBIT_USAGE_CHECK
1525 if ((IS_OPAQUE_LSA(lsah->type) &&
1526 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1527 || (! IS_OPAQUE_LSA(lsah->type) &&
1528 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1529 {
1530 /*
1531 * This neighbor must know the exact usage of O-bit;
1532 * the bit will be set in Type-9,10,11 LSAs only.
1533 */
1534 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1535 continue;
1536 }
1537#endif /* STRICT_OBIT_USAGE_CHECK */
1538
1539 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1540 if (lsah->type == OSPF_OPAQUE_AS_LSA
1541 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1542 {
1543 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001544 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 +00001545 continue;
1546 }
1547 }
1548 else if (IS_OPAQUE_LSA(lsah->type))
1549 {
1550 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1551 continue;
1552 }
1553#endif /* HAVE_OPAQUE_LSA */
1554
1555 /* Create OSPF LSA instance. */
1556 lsa = ospf_lsa_new ();
1557
1558 /* We may wish to put some error checking if type NSSA comes in
1559 and area not in NSSA mode */
1560 switch (lsah->type)
1561 {
1562 case OSPF_AS_EXTERNAL_LSA:
1563#ifdef HAVE_OPAQUE_LSA
1564 case OSPF_OPAQUE_AS_LSA:
1565 lsa->area = NULL;
1566 break;
1567 case OSPF_OPAQUE_LINK_LSA:
1568 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1569 /* Fallthrough */
1570#endif /* HAVE_OPAQUE_LSA */
1571 default:
1572 lsa->area = oi->area;
1573 break;
1574 }
1575
1576 lsa->data = ospf_lsa_data_new (length);
1577 memcpy (lsa->data, lsah, length);
1578
1579 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001580 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001581 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1582 listnode_add (lsas, lsa);
1583 }
1584
1585 return lsas;
1586}
1587
1588/* Cleanup Update list. */
1589void
hasso52dc7ee2004-09-23 19:18:23 +00001590ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001591{
hasso52dc7ee2004-09-23 19:18:23 +00001592 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001593 struct ospf_lsa *lsa;
1594
1595 for (node = listhead (lsas); node; nextnode (node))
1596 if ((lsa = getdata (node)) != NULL)
1597 ospf_lsa_discard (lsa);
1598
1599 list_delete (lsas);
1600}
1601
1602/* OSPF Link State Update message read -- RFC2328 Section 13. */
1603void
1604ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1605 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1606{
1607 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001608 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001609#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001610 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001611#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001612 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001613 struct ospf_lsa *lsa = NULL;
1614 /* unsigned long ls_req_found = 0; */
1615
1616 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1617
1618 /* Increment statistics. */
1619 oi->ls_upd_in++;
1620
1621 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001622 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001623 if (nbr == NULL)
1624 {
1625 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1626 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1627 return;
1628 }
1629
1630 /* Check neighbor state. */
1631 if (nbr->state < NSM_Exchange)
1632 {
ajs3aa8d5f2004-12-11 18:00:06 +00001633 zlog_warn ("Link State Update: "
1634 "Neighbor[%s] state %s is less than Exchange",
1635 inet_ntoa (ospfh->router_id),
1636 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001637 return;
1638 }
1639
1640 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1641 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1642 * of section 13.
1643 */
1644 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1645
1646#ifdef HAVE_OPAQUE_LSA
1647 /*
1648 * Prepare two kinds of lists to clean up unwanted self-originated
1649 * Opaque-LSAs from the routing domain as soon as possible.
1650 */
1651 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1652 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1653
1654 /*
1655 * If self-originated Opaque-LSAs that have flooded before restart
1656 * are contained in the received LSUpd message, corresponding LSReq
1657 * messages to be sent may have to be modified.
1658 * To eliminate possible race conditions such that flushing and normal
1659 * updating for the same LSA would take place alternately, this trick
1660 * must be done before entering to the loop below.
1661 */
1662 ospf_opaque_adjust_lsreq (nbr, lsas);
1663#endif /* HAVE_OPAQUE_LSA */
1664
1665#define DISCARD_LSA(L,N) {\
1666 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001667 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 +00001668 ospf_lsa_discard (L); \
1669 continue; }
1670
1671 /* Process each LSA received in the one packet. */
1672 for (node = listhead (lsas); node; node = next)
1673 {
1674 struct ospf_lsa *ls_ret, *current;
1675 int ret = 1;
1676
1677 next = node->next;
1678
1679 lsa = getdata (node);
1680
paul718e3742002-12-13 20:15:29 +00001681 if (IS_DEBUG_OSPF_NSSA)
1682 {
1683 char buf1[INET_ADDRSTRLEN];
1684 char buf2[INET_ADDRSTRLEN];
1685 char buf3[INET_ADDRSTRLEN];
1686
ajs2a42e282004-12-08 18:43:03 +00001687 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001688 lsa->data->type,
1689 inet_ntop (AF_INET, &ospfh->router_id,
1690 buf1, INET_ADDRSTRLEN),
1691 inet_ntop (AF_INET, &lsa->data->id,
1692 buf2, INET_ADDRSTRLEN),
1693 inet_ntop (AF_INET, &lsa->data->adv_router,
1694 buf3, INET_ADDRSTRLEN));
1695 }
paul718e3742002-12-13 20:15:29 +00001696
1697 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1698
1699 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1700
1701 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1702
1703 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1704
1705 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1706
1707 /* Do take in Type-7's if we are an NSSA */
1708
1709 /* If we are also an ABR, later translate them to a Type-5 packet */
1710
1711 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1712 translate them to a separate Type-5 packet. */
1713
1714 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1715 /* Reject from STUB or NSSA */
1716 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1717 {
1718 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001719 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001720 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001721 }
1722
paul718e3742002-12-13 20:15:29 +00001723 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1724 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1725 {
1726 DISCARD_LSA (lsa,2);
1727 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001728 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001729 }
paul718e3742002-12-13 20:15:29 +00001730
1731 /* Find the LSA in the current database. */
1732
1733 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1734
1735 /* If the LSA's LS age is equal to MaxAge, and there is currently
1736 no instance of the LSA in the router's link state database,
1737 and none of router's neighbors are in states Exchange or Loading,
1738 then take the following actions. */
1739
1740 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001741 (ospf_nbr_count (oi, NSM_Exchange) +
1742 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001743 {
1744 /* Response Link State Acknowledgment. */
1745 ospf_ls_ack_send (nbr, lsa);
1746
1747 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001748 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1749 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001750 DISCARD_LSA (lsa, 3);
1751 }
1752
1753#ifdef HAVE_OPAQUE_LSA
1754 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001755 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001756 {
1757 /*
1758 * Even if initial flushing seems to be completed, there might
1759 * be a case that self-originated LSA with MaxAge still remain
1760 * in the routing domain.
1761 * Just send an LSAck message to cease retransmission.
1762 */
1763 if (IS_LSA_MAXAGE (lsa))
1764 {
1765 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1766 ospf_ls_ack_send (nbr, lsa);
1767 ospf_lsa_discard (lsa);
1768
1769 if (current != NULL && ! IS_LSA_MAXAGE (current))
1770 ospf_opaque_lsa_refresh_schedule (current);
1771 continue;
1772 }
1773
1774 /*
1775 * If an instance of self-originated Opaque-LSA is not found
1776 * in the LSDB, there are some possible cases here.
1777 *
1778 * 1) This node lost opaque-capability after restart.
1779 * 2) Else, a part of opaque-type is no more supported.
1780 * 3) Else, a part of opaque-id is no more supported.
1781 *
1782 * Anyway, it is still this node's responsibility to flush it.
1783 * Otherwise, the LSA instance remains in the routing domain
1784 * until its age reaches to MaxAge.
1785 */
1786 if (current == NULL)
1787 {
1788 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001789 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001790
1791 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1792 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1793 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1794 continue;
1795 }
1796 }
1797#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001798 /* It might be happen that received LSA is self-originated network LSA, but
1799 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1800 * Link State ID is one of the router's own IP interface addresses but whose
1801 * Advertising Router is not equal to the router's own Router ID
1802 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1803 */
1804
1805 if(lsa->data->type == OSPF_NETWORK_LSA)
1806 {
hasso52dc7ee2004-09-23 19:18:23 +00001807 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001808 int Flag = 0;
1809
1810 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1811 {
1812 struct ospf_interface *out_if = getdata(oi_node);
1813 if(out_if == NULL)
1814 break;
1815
1816 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1817 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1818 {
1819 if(out_if->network_lsa_self)
1820 {
1821 ospf_lsa_flush_area(lsa,out_if->area);
1822 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001823 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001824 lsa, (int) lsa->data->type);
1825 ospf_lsa_discard (lsa);
1826 Flag = 1;
1827 }
1828 break;
1829 }
1830 }
1831 if(Flag)
1832 continue;
1833 }
paul718e3742002-12-13 20:15:29 +00001834
1835 /* (5) Find the instance of this LSA that is currently contained
1836 in the router's link state database. If there is no
1837 database copy, or the received LSA is more recent than
1838 the database copy the following steps must be performed. */
1839
1840 if (current == NULL ||
1841 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1842 {
1843 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001844 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001845 DISCARD_LSA (lsa, 4);
1846 continue;
1847 }
1848
1849 /* (6) Else, If there is an instance of the LSA on the sending
1850 neighbor's Link state request list, an error has occurred in
1851 the Database Exchange process. In this case, restart the
1852 Database Exchange process by generating the neighbor event
1853 BadLSReq for the sending neighbor and stop processing the
1854 Link State Update packet. */
1855
1856 if (ospf_ls_request_lookup (nbr, lsa))
1857 {
1858 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001859 zlog_warn("LSA[%s] instance exists on Link state request list",
1860 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001861
1862 /* Clean list of LSAs. */
1863 ospf_upd_list_clean (lsas);
1864 /* this lsa is not on lsas list already. */
1865 ospf_lsa_discard (lsa);
1866#ifdef HAVE_OPAQUE_LSA
1867 list_delete (mylsa_acks);
1868 list_delete (mylsa_upds);
1869#endif /* HAVE_OPAQUE_LSA */
1870 return;
1871 }
1872
1873 /* If the received LSA is the same instance as the database copy
1874 (i.e., neither one is more recent) the following two steps
1875 should be performed: */
1876
1877 if (ret == 0)
1878 {
1879 /* If the LSA is listed in the Link state retransmission list
1880 for the receiving adjacency, the router itself is expecting
1881 an acknowledgment for this LSA. The router should treat the
1882 received LSA as an acknowledgment by removing the LSA from
1883 the Link state retransmission list. This is termed an
1884 "implied acknowledgment". */
1885
1886 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1887
1888 if (ls_ret != NULL)
1889 {
1890 ospf_ls_retransmit_delete (nbr, ls_ret);
1891
1892 /* Delayed acknowledgment sent if advertisement received
1893 from Designated Router, otherwise do nothing. */
1894 if (oi->state == ISM_Backup)
1895 if (NBR_IS_DR (nbr))
1896 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1897
1898 DISCARD_LSA (lsa, 5);
1899 }
1900 else
1901 /* Acknowledge the receipt of the LSA by sending a
1902 Link State Acknowledgment packet back out the receiving
1903 interface. */
1904 {
1905 ospf_ls_ack_send (nbr, lsa);
1906 DISCARD_LSA (lsa, 6);
1907 }
1908 }
1909
1910 /* The database copy is more recent. If the database copy
1911 has LS age equal to MaxAge and LS sequence number equal to
1912 MaxSequenceNumber, simply discard the received LSA without
1913 acknowledging it. (In this case, the LSA's LS sequence number is
1914 wrapping, and the MaxSequenceNumber LSA must be completely
1915 flushed before any new LSA instance can be introduced). */
1916
1917 else if (ret > 0) /* Database copy is more recent */
1918 {
1919 if (IS_LSA_MAXAGE (current) &&
1920 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1921 {
1922 DISCARD_LSA (lsa, 7);
1923 }
1924 /* Otherwise, as long as the database copy has not been sent in a
1925 Link State Update within the last MinLSArrival seconds, send the
1926 database copy back to the sending neighbor, encapsulated within
1927 a Link State Update Packet. The Link State Update Packet should
1928 be sent directly to the neighbor. In so doing, do not put the
1929 database copy of the LSA on the neighbor's link state
1930 retransmission list, and do not acknowledge the received (less
1931 recent) LSA instance. */
1932 else
1933 {
1934 struct timeval now;
1935
1936 gettimeofday (&now, NULL);
1937
1938 if (tv_cmp (tv_sub (now, current->tv_orig),
1939 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1940 /* Trap NSSA type later.*/
1941 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1942 DISCARD_LSA (lsa, 8);
1943 }
1944 }
1945 }
1946
1947#ifdef HAVE_OPAQUE_LSA
1948 /*
1949 * Now that previously originated Opaque-LSAs those which not yet
1950 * installed into LSDB are captured, take several steps to clear
1951 * them completely from the routing domain, before proceeding to
1952 * origination for the current target Opaque-LSAs.
1953 */
1954 while (listcount (mylsa_acks) > 0)
1955 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1956
1957 if (listcount (mylsa_upds) > 0)
1958 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1959
1960 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001961 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001962#endif /* HAVE_OPAQUE_LSA */
1963
1964 assert (listcount (lsas) == 0);
1965 list_delete (lsas);
1966}
1967
1968/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1969void
1970ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1971 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1972{
1973 struct ospf_neighbor *nbr;
1974#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001975 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001976#endif /* HAVE_OPAQUE_LSA */
1977
1978 /* increment statistics. */
1979 oi->ls_ack_in++;
1980
pauld3f0d622004-05-05 15:27:15 +00001981 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001982 if (nbr == NULL)
1983 {
1984 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1985 inet_ntoa (ospfh->router_id));
1986 return;
1987 }
1988
1989 if (nbr->state < NSM_Exchange)
1990 {
ajs3aa8d5f2004-12-11 18:00:06 +00001991 zlog_warn ("Link State Acknowledgment: "
1992 "Neighbor[%s] state %s is less than Exchange",
1993 inet_ntoa (ospfh->router_id),
1994 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001995 return;
1996 }
1997
1998#ifdef HAVE_OPAQUE_LSA
1999 opaque_acks = list_new ();
2000#endif /* HAVE_OPAQUE_LSA */
2001
2002 while (size >= OSPF_LSA_HEADER_SIZE)
2003 {
2004 struct ospf_lsa *lsa, *lsr;
2005
2006 lsa = ospf_lsa_new ();
2007 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2008
2009 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2010 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002011 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002012
2013 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2014 {
2015 lsa->data = NULL;
2016 ospf_lsa_discard (lsa);
2017 continue;
2018 }
2019
2020 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2021
2022 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2023 {
2024#ifdef HAVE_OPAQUE_LSA
2025 /* Keep this LSA entry for later reference. */
2026 if (IS_OPAQUE_LSA (lsr->data->type))
2027 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2028#endif /* HAVE_OPAQUE_LSA */
2029
2030 ospf_ls_retransmit_delete (nbr, lsr);
2031 }
2032
2033 lsa->data = NULL;
2034 ospf_lsa_discard (lsa);
2035 }
2036
2037#ifdef HAVE_OPAQUE_LSA
2038 if (listcount (opaque_acks) > 0)
2039 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2040
2041 list_delete (opaque_acks);
2042 return;
2043#endif /* HAVE_OPAQUE_LSA */
2044}
2045
ajs038163f2005-02-17 19:55:59 +00002046static struct stream *
paul718e3742002-12-13 20:15:29 +00002047ospf_recv_packet (int fd, struct interface **ifp)
2048{
2049 int ret;
2050 struct ip iph;
2051 u_int16_t ip_len;
2052 struct stream *ibuf;
2053 unsigned int ifindex = 0;
2054 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002055 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002056 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002057 struct msghdr msgh;
2058
paul68defd62004-09-27 07:27:13 +00002059 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002060 msgh.msg_iov = &iov;
2061 msgh.msg_iovlen = 1;
2062 msgh.msg_control = (caddr_t) buff;
2063 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002064
ajs038163f2005-02-17 19:55:59 +00002065 /* XXX Is there an upper limit on the size of these packets? If there is,
2066 it would be more efficient to read the whole packet in one shot without
2067 peeking (this would cut down from 2 system calls to 1). And this would
2068 make the error-handling logic a bit more robust. */
paul718e3742002-12-13 20:15:29 +00002069 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2070
2071 if (ret != sizeof (iph))
2072 {
ajs038163f2005-02-17 19:55:59 +00002073 if (ret > 0)
2074 {
2075 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2076 "(ip header size is %u)",
2077 ret, (u_int)sizeof(iph));
2078 recvfrom (fd, (void *)&iph, ret, 0, NULL, 0);
2079 }
2080 else
2081 zlog_warn("ospf_recv_packet: recvfrom returned %d: %s",
2082 ret, safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +00002083 return NULL;
2084 }
paul18b12c32004-10-05 14:38:29 +00002085
2086 sockopt_iphdrincl_swab_systoh (&iph);
2087
paul6b333612004-10-11 10:11:25 +00002088 ip_len = iph.ip_len;
2089
paul239aecc2003-12-08 10:34:54 +00002090#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002091 /*
2092 * Kernel network code touches incoming IP header parameters,
2093 * before protocol specific processing.
2094 *
2095 * 1) Convert byteorder to host representation.
2096 * --> ip_len, ip_id, ip_off
2097 *
2098 * 2) Adjust ip_len to strip IP header size!
2099 * --> If user process receives entire IP packet via RAW
2100 * socket, it must consider adding IP header size to
2101 * the "ip_len" field of "ip" structure.
2102 *
2103 * For more details, see <netinet/ip_input.c>.
2104 */
2105 ip_len = ip_len + (iph.ip_hl << 2);
2106#endif
2107
paulbfdc44a2005-02-14 23:48:42 +00002108 if ( (ibuf = stream_new (ip_len)) == NULL)
2109 return NULL;
paul658b03a2005-02-15 10:10:55 +00002110 iov.iov_base = STREAM_DATA (ibuf);
2111 iov.iov_len = ip_len;
paulbfdc44a2005-02-14 23:48:42 +00002112
2113 ret = stream_recvmsg (ibuf, fd, &msgh, 0, ip_len);
paul718e3742002-12-13 20:15:29 +00002114
paul863082d2004-08-19 04:43:43 +00002115 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002116
2117 *ifp = if_lookup_by_index (ifindex);
2118
2119 if (ret != ip_len)
2120 {
2121 zlog_warn ("ospf_recv_packet short read. "
2122 "ip_len %d bytes read %d", ip_len, ret);
2123 stream_free (ibuf);
2124 return NULL;
2125 }
2126
2127 return ibuf;
2128}
2129
2130struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002131ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002132 struct ip *iph, struct ospf_header *ospfh)
2133{
2134 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002135 struct ospf_vl_data *vl_data;
2136 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002137 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002138
2139 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2140 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002141 return NULL;
paul718e3742002-12-13 20:15:29 +00002142
pauld3f0d622004-05-05 15:27:15 +00002143 /* look for local OSPF interface matching the destination
2144 * to determine Area ID. We presume therefore the destination address
2145 * is unique, or at least (for "unnumbered" links), not used in other
2146 * areas
2147 */
2148 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2149 iph->ip_dst)) == NULL)
2150 return NULL;
paul718e3742002-12-13 20:15:29 +00002151
paul020709f2003-04-04 02:44:16 +00002152 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002153 {
2154 if ((vl_data = getdata (node)) == NULL)
2155 continue;
2156
paul020709f2003-04-04 02:44:16 +00002157 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002158 if (!vl_area)
2159 continue;
2160
2161 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2162 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2163 {
2164 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002165 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002166 IF_NAME (vl_data->vl_oi));
2167 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2168 {
2169 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002170 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002171 return NULL;
2172 }
2173
2174 return vl_data->vl_oi;
2175 }
2176 }
2177
2178 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002179 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002180
pauld3f0d622004-05-05 15:27:15 +00002181 return NULL;
paul718e3742002-12-13 20:15:29 +00002182}
2183
2184int
2185ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2186{
2187 /* Check match the Area ID of the receiving interface. */
2188 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2189 return 1;
2190
2191 return 0;
2192}
2193
2194/* Unbound socket will accept any Raw IP packets if proto is matched.
2195 To prevent it, compare src IP address and i/f address with masking
2196 i/f network mask. */
2197int
2198ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2199{
2200 struct in_addr mask, me, him;
2201
2202 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2203 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2204 return 1;
2205
2206 masklen2ip (oi->address->prefixlen, &mask);
2207
2208 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2209 him.s_addr = ip_src.s_addr & mask.s_addr;
2210
2211 if (IPV4_ADDR_SAME (&me, &him))
2212 return 1;
2213
2214 return 0;
2215}
2216
2217int
2218ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2219 struct ospf_header *ospfh)
2220{
2221 int ret = 0;
2222 struct crypt_key *ck;
2223
2224 switch (ntohs (ospfh->auth_type))
2225 {
2226 case OSPF_AUTH_NULL:
2227 ret = 1;
2228 break;
2229 case OSPF_AUTH_SIMPLE:
2230 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2231 ret = 1;
2232 else
2233 ret = 0;
2234 break;
2235 case OSPF_AUTH_CRYPTOGRAPHIC:
2236 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2237 {
2238 ret = 0;
2239 break;
2240 }
2241
2242 /* This is very basic, the digest processing is elsewhere */
2243 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2244 ospfh->u.crypt.key_id == ck->key_id &&
2245 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2246 ret = 1;
2247 else
2248 ret = 0;
2249 break;
2250 default:
2251 ret = 0;
2252 break;
2253 }
2254
2255 return ret;
2256}
2257
2258int
2259ospf_check_sum (struct ospf_header *ospfh)
2260{
2261 u_int32_t ret;
2262 u_int16_t sum;
2263 int in_cksum (void *ptr, int nbytes);
2264
2265 /* clear auth_data for checksum. */
2266 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2267
2268 /* keep checksum and clear. */
2269 sum = ospfh->checksum;
2270 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2271
2272 /* calculate checksum. */
2273 ret = in_cksum (ospfh, ntohs (ospfh->length));
2274
2275 if (ret != sum)
2276 {
2277 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2278 ret, sum);
2279 return 0;
2280 }
2281
2282 return 1;
2283}
2284
2285/* OSPF Header verification. */
2286int
2287ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2288 struct ip *iph, struct ospf_header *ospfh)
2289{
2290 /* check version. */
2291 if (ospfh->version != OSPF_VERSION)
2292 {
2293 zlog_warn ("interface %s: ospf_read version number mismatch.",
2294 IF_NAME (oi));
2295 return -1;
2296 }
2297
2298 /* Check Area ID. */
2299 if (!ospf_check_area_id (oi, ospfh))
2300 {
2301 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2302 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2303 return -1;
2304 }
2305
2306 /* Check network mask, Silently discarded. */
2307 if (! ospf_check_network_mask (oi, iph->ip_src))
2308 {
2309 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2310 IF_NAME (oi), inet_ntoa (iph->ip_src));
2311 return -1;
2312 }
2313
2314 /* Check authentication. */
2315 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2316 {
2317 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2318 IF_NAME (oi));
2319 return -1;
2320 }
2321
2322 if (! ospf_check_auth (oi, ibuf, ospfh))
2323 {
2324 zlog_warn ("interface %s: ospf_read authentication failed.",
2325 IF_NAME (oi));
2326 return -1;
2327 }
2328
2329 /* if check sum is invalid, packet is discarded. */
2330 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2331 {
2332 if (! ospf_check_sum (ospfh))
2333 {
2334 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2335 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2336 return -1;
2337 }
2338 }
2339 else
2340 {
2341 if (ospfh->checksum != 0)
2342 return -1;
2343 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2344 {
2345 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2346 IF_NAME (oi));
2347 return -1;
2348 }
2349 }
2350
2351 return 0;
2352}
2353
2354/* Starting point of packet process function. */
2355int
2356ospf_read (struct thread *thread)
2357{
2358 int ret;
2359 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002360 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002361 struct ospf_interface *oi;
2362 struct ip *iph;
2363 struct ospf_header *ospfh;
2364 u_int16_t length;
2365 struct interface *ifp;
2366
2367 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002368 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002369
2370 /* prepare for next packet. */
2371 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002372
2373 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002374 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002375 if (ibuf == NULL)
2376 return -1;
2377
paul06f953f2004-10-22 17:00:38 +00002378 iph = (struct ip *) STREAM_DATA (ibuf);
2379 sockopt_iphdrincl_swab_systoh (iph);
2380
paulac191232004-10-22 12:05:17 +00002381 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002382 /* Handle cases where the platform does not support retrieving the ifindex,
2383 and also platforms (such as Solaris 8) that claim to support ifindex
2384 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002385 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002386
pauld3f0d622004-05-05 15:27:15 +00002387 if (ifp == NULL)
2388 {
2389 stream_free (ibuf);
2390 return 0;
2391 }
paul718e3742002-12-13 20:15:29 +00002392
2393 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002394 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002395 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002396
paul718e3742002-12-13 20:15:29 +00002397 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002398 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002399 {
pauld3241812003-09-29 12:42:39 +00002400 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2401 {
ajs2a42e282004-12-08 18:43:03 +00002402 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002403 inet_ntoa (iph->ip_src));
2404 }
paul718e3742002-12-13 20:15:29 +00002405 stream_free (ibuf);
2406 return 0;
2407 }
2408
2409 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002410 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002411
2412 /* Get ospf packet header. */
2413 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2414
2415 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002416 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002417
2418 /* if no local ospf_interface,
2419 * or header area is backbone but ospf_interface is not
2420 * check for VLINK interface
2421 */
2422 if ( (oi == NULL) ||
2423 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2424 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2425 )
2426 {
2427 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2428 {
2429 zlog_warn ("Packet from [%s] received on link %s"
2430 " but no ospf_interface",
2431 inet_ntoa (iph->ip_src), ifp->name);
2432 stream_free (ibuf);
2433 return 0;
2434 }
2435 }
2436
2437 /* else it must be a local ospf interface, check it was received on
2438 * correct link
2439 */
2440 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002441 {
2442 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002443 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002444 stream_free (ibuf);
2445 return 0;
2446 }
ajs847947f2005-02-02 18:38:48 +00002447 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002448 {
ajsba6454e2005-02-08 15:37:30 +00002449 char buf[2][INET_ADDRSTRLEN];
2450 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002451 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002452 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2453 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2454 ifp->name, if_flag_dump(ifp->flags));
ajsc3eab872005-01-29 15:52:07 +00002455 stream_free (ibuf);
ajsba6454e2005-02-08 15:37:30 +00002456 /* Fix multicast memberships? */
2457 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2458 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2459 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2460 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2461 if (oi->multicast_memberships)
2462 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002463 return 0;
2464 }
paul718e3742002-12-13 20:15:29 +00002465
2466 /*
2467 * If the received packet is destined for AllDRouters, the packet
2468 * should be accepted only if the received ospf interface state is
2469 * either DR or Backup -- endo.
2470 */
2471 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2472 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2473 {
ajsba6454e2005-02-08 15:37:30 +00002474 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002475 inet_ntoa (iph->ip_src), IF_NAME (oi),
2476 LOOKUP (ospf_ism_state_msg, oi->state));
2477 stream_free (ibuf);
ajsba6454e2005-02-08 15:37:30 +00002478 /* Try to fix multicast membership. */
2479 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2480 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002481 return 0;
2482 }
2483
2484 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002485 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2486 {
paul718e3742002-12-13 20:15:29 +00002487 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002488 {
ajs2a42e282004-12-08 18:43:03 +00002489 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002490 ospf_packet_dump (ibuf);
2491 }
paul718e3742002-12-13 20:15:29 +00002492
ajs2a42e282004-12-08 18:43:03 +00002493 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002494 ospf_packet_type_str[ospfh->type],
2495 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002496 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2497 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002498
2499 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002500 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002501 }
paul718e3742002-12-13 20:15:29 +00002502
2503 /* Some header verification. */
2504 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2505 if (ret < 0)
2506 {
pauld3241812003-09-29 12:42:39 +00002507 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2508 {
ajs2a42e282004-12-08 18:43:03 +00002509 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002510 "dropping.",
2511 ospf_packet_type_str[ospfh->type],
2512 inet_ntoa (iph->ip_src));
2513 }
paul718e3742002-12-13 20:15:29 +00002514 stream_free (ibuf);
2515 return ret;
2516 }
2517
paul9985f832005-02-09 15:51:56 +00002518 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002519
2520 /* Adjust size to message length. */
2521 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2522
2523 /* Read rest of the packet and call each sort of packet routine. */
2524 switch (ospfh->type)
2525 {
2526 case OSPF_MSG_HELLO:
2527 ospf_hello (iph, ospfh, ibuf, oi, length);
2528 break;
2529 case OSPF_MSG_DB_DESC:
2530 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2531 break;
2532 case OSPF_MSG_LS_REQ:
2533 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2534 break;
2535 case OSPF_MSG_LS_UPD:
2536 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2537 break;
2538 case OSPF_MSG_LS_ACK:
2539 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2540 break;
2541 default:
2542 zlog (NULL, LOG_WARNING,
2543 "interface %s: OSPF packet header type %d is illegal",
2544 IF_NAME (oi), ospfh->type);
2545 break;
2546 }
2547
2548 stream_free (ibuf);
2549 return 0;
2550}
2551
2552/* Make OSPF header. */
2553void
2554ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2555{
2556 struct ospf_header *ospfh;
2557
2558 ospfh = (struct ospf_header *) STREAM_DATA (s);
2559
2560 ospfh->version = (u_char) OSPF_VERSION;
2561 ospfh->type = (u_char) type;
2562
paul68980082003-03-25 05:07:42 +00002563 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002564
2565 ospfh->checksum = 0;
2566 ospfh->area_id = oi->area->area_id;
2567 ospfh->auth_type = htons (ospf_auth_type (oi));
2568
2569 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2570
paul9985f832005-02-09 15:51:56 +00002571 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002572}
2573
2574/* Make Authentication Data. */
2575int
2576ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2577{
2578 struct crypt_key *ck;
2579
2580 switch (ospf_auth_type (oi))
2581 {
2582 case OSPF_AUTH_NULL:
2583 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2584 break;
2585 case OSPF_AUTH_SIMPLE:
2586 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2587 OSPF_AUTH_SIMPLE_SIZE);
2588 break;
2589 case OSPF_AUTH_CRYPTOGRAPHIC:
2590 /* If key is not set, then set 0. */
2591 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2592 {
2593 ospfh->u.crypt.zero = 0;
2594 ospfh->u.crypt.key_id = 0;
2595 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2596 }
2597 else
2598 {
2599 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2600 ospfh->u.crypt.zero = 0;
2601 ospfh->u.crypt.key_id = ck->key_id;
2602 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2603 }
2604 /* note: the seq is done in ospf_make_md5_digest() */
2605 break;
2606 default:
2607 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2608 break;
2609 }
2610
2611 return 0;
2612}
2613
2614/* Fill rest of OSPF header. */
2615void
2616ospf_fill_header (struct ospf_interface *oi,
2617 struct stream *s, u_int16_t length)
2618{
2619 struct ospf_header *ospfh;
2620
2621 ospfh = (struct ospf_header *) STREAM_DATA (s);
2622
2623 /* Fill length. */
2624 ospfh->length = htons (length);
2625
2626 /* Calculate checksum. */
2627 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2628 ospfh->checksum = in_cksum (ospfh, length);
2629 else
2630 ospfh->checksum = 0;
2631
2632 /* Add Authentication Data. */
2633 ospf_make_auth (oi, ospfh);
2634}
2635
2636int
2637ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2638{
2639 struct ospf_neighbor *nbr;
2640 struct route_node *rn;
2641 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2642 struct in_addr mask;
2643 unsigned long p;
2644 int flag = 0;
2645
2646 /* Set netmask of interface. */
2647 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2648 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2649 masklen2ip (oi->address->prefixlen, &mask);
2650 else
2651 memset ((char *) &mask, 0, sizeof (struct in_addr));
2652 stream_put_ipv4 (s, mask.s_addr);
2653
2654 /* Set Hello Interval. */
2655 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2656
2657 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002658 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002659 OPTIONS(oi), IF_NAME (oi));
2660
2661 /* Set Options. */
2662 stream_putc (s, OPTIONS (oi));
2663
2664 /* Set Router Priority. */
2665 stream_putc (s, PRIORITY (oi));
2666
2667 /* Set Router Dead Interval. */
2668 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2669
2670 /* Set Designated Router. */
2671 stream_put_ipv4 (s, DR (oi).s_addr);
2672
paul9985f832005-02-09 15:51:56 +00002673 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002674
2675 /* Set Backup Designated Router. */
2676 stream_put_ipv4 (s, BDR (oi).s_addr);
2677
2678 /* Add neighbor seen. */
2679 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002680 if ((nbr = rn->info))
2681 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2682 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2683 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2684 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002685 {
2686 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002687 if (nbr->d_router.s_addr != 0
2688 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2689 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2690 flag = 1;
paul718e3742002-12-13 20:15:29 +00002691
2692 stream_put_ipv4 (s, nbr->router_id.s_addr);
2693 length += 4;
2694 }
2695
2696 /* Let neighbor generate BackupSeen. */
2697 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002698 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002699
2700 return length;
2701}
2702
2703int
2704ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2705 struct stream *s)
2706{
2707 struct ospf_lsa *lsa;
2708 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2709 u_char options;
2710 unsigned long pp;
2711 int i;
2712 struct ospf_lsdb *lsdb;
2713
2714 /* Set Interface MTU. */
2715 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2716 stream_putw (s, 0);
2717 else
2718 stream_putw (s, oi->ifp->mtu);
2719
2720 /* Set Options. */
2721 options = OPTIONS (oi);
2722#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002723 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002724 {
2725 if (IS_SET_DD_I (nbr->dd_flags)
2726 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2727 /*
2728 * Set O-bit in the outgoing DD packet for capablity negotiation,
2729 * if one of following case is applicable.
2730 *
2731 * 1) WaitTimer expiration event triggered the neighbor state to
2732 * change to Exstart, but no (valid) DD packet has received
2733 * from the neighbor yet.
2734 *
2735 * 2) At least one DD packet with O-bit on has received from the
2736 * neighbor.
2737 */
2738 SET_FLAG (options, OSPF_OPTION_O);
2739 }
2740#endif /* HAVE_OPAQUE_LSA */
2741 stream_putc (s, options);
2742
2743 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002744 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002745 stream_putc (s, nbr->dd_flags);
2746
2747 /* Set DD Sequence Number. */
2748 stream_putl (s, nbr->dd_seqnum);
2749
2750 if (ospf_db_summary_isempty (nbr))
2751 {
2752 if (nbr->state >= NSM_Exchange)
2753 {
2754 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2755 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002756 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002757 }
2758 return length;
2759 }
2760
2761 /* Describe LSA Header from Database Summary List. */
2762 lsdb = &nbr->db_sum;
2763
2764 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2765 {
2766 struct route_table *table = lsdb->type[i].db;
2767 struct route_node *rn;
2768
2769 for (rn = route_top (table); rn; rn = route_next (rn))
2770 if ((lsa = rn->info) != NULL)
2771 {
2772#ifdef HAVE_OPAQUE_LSA
2773 if (IS_OPAQUE_LSA (lsa->data->type)
2774 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2775 {
2776 /* Suppress advertising opaque-informations. */
2777 /* Remove LSA from DB summary list. */
2778 ospf_lsdb_delete (lsdb, lsa);
2779 continue;
2780 }
2781#endif /* HAVE_OPAQUE_LSA */
2782
2783 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2784 {
2785 struct lsa_header *lsah;
2786 u_int16_t ls_age;
2787
2788 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002789 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002790 break;
2791
2792 /* Keep pointer to LS age. */
2793 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002794 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002795
2796 /* Proceed stream pointer. */
2797 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2798 length += OSPF_LSA_HEADER_SIZE;
2799
2800 /* Set LS age. */
2801 ls_age = LS_AGE (lsa);
2802 lsah->ls_age = htons (ls_age);
2803
2804 }
2805
2806 /* Remove LSA from DB summary list. */
2807 ospf_lsdb_delete (lsdb, lsa);
2808 }
2809 }
2810
2811 return length;
2812}
2813
2814int
2815ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2816 unsigned long delta, struct ospf_neighbor *nbr,
2817 struct ospf_lsa *lsa)
2818{
2819 struct ospf_interface *oi;
2820
2821 oi = nbr->oi;
2822
2823 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002824 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002825 return 0;
2826
2827 stream_putl (s, lsa->data->type);
2828 stream_put_ipv4 (s, lsa->data->id.s_addr);
2829 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2830
2831 ospf_lsa_unlock (nbr->ls_req_last);
2832 nbr->ls_req_last = ospf_lsa_lock (lsa);
2833
2834 *length += 12;
2835 return 1;
2836}
2837
2838int
2839ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2840{
2841 struct ospf_lsa *lsa;
2842 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002843 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002844 struct route_table *table;
2845 struct route_node *rn;
2846 int i;
2847 struct ospf_lsdb *lsdb;
2848
2849 lsdb = &nbr->ls_req;
2850
2851 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2852 {
2853 table = lsdb->type[i].db;
2854 for (rn = route_top (table); rn; rn = route_next (rn))
2855 if ((lsa = (rn->info)) != NULL)
2856 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2857 {
2858 route_unlock_node (rn);
2859 break;
2860 }
2861 }
2862 return length;
2863}
2864
2865int
2866ls_age_increment (struct ospf_lsa *lsa, int delay)
2867{
2868 int age;
2869
2870 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2871
2872 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2873}
2874
2875int
hasso52dc7ee2004-09-23 19:18:23 +00002876ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002877{
2878 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002879 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002880 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002881 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002882 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002883 unsigned long pp;
2884 int count = 0;
2885
2886 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002887 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002888
paul9985f832005-02-09 15:51:56 +00002889 pp = stream_get_endp (s);
2890 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002891
gdt86f1fd92005-01-10 14:20:43 +00002892 /* Calculate amount of packet usable for data. */
2893 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2894
paul718e3742002-12-13 20:15:29 +00002895 while ((node = listhead (update)) != NULL)
2896 {
2897 struct lsa_header *lsah;
2898 u_int16_t ls_age;
2899
2900 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002901 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002902
2903 lsa = getdata (node);
2904 assert (lsa);
2905 assert (lsa->data);
2906
paul68b73392004-09-12 14:21:37 +00002907 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002908 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002909 break;
2910
paul718e3742002-12-13 20:15:29 +00002911 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002912 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002913
2914 /* Put LSA to Link State Request. */
2915 stream_put (s, lsa->data, ntohs (lsa->data->length));
2916
2917 /* Set LS age. */
2918 /* each hop must increment an lsa_age by transmit_delay
2919 of OSPF interface */
2920 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2921 lsah->ls_age = htons (ls_age);
2922
2923 length += ntohs (lsa->data->length);
2924 count++;
2925
2926 list_delete_node (update, node);
2927 ospf_lsa_unlock (lsa);
2928 }
2929
2930 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002931 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002932
2933 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002934 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002935 return length;
2936}
2937
2938int
hasso52dc7ee2004-09-23 19:18:23 +00002939ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002940{
hasso52dc7ee2004-09-23 19:18:23 +00002941 struct list *rm_list;
2942 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002943 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002944 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002945 struct ospf_lsa *lsa;
2946
2947 rm_list = list_new ();
2948
2949 for (node = listhead (ack); node; nextnode (node))
2950 {
2951 lsa = getdata (node);
2952 assert (lsa);
2953
gdt86f1fd92005-01-10 14:20:43 +00002954 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002955 break;
2956
2957 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2958 length += OSPF_LSA_HEADER_SIZE;
2959
2960 listnode_add (rm_list, lsa);
2961 }
2962
2963 /* Remove LSA from LS-Ack list. */
2964 for (node = listhead (rm_list); node; nextnode (node))
2965 {
2966 lsa = (struct ospf_lsa *) getdata (node);
2967
2968 listnode_delete (ack, lsa);
2969 ospf_lsa_unlock (lsa);
2970 }
2971
2972 list_delete (rm_list);
2973
2974 return length;
2975}
2976
2977void
2978ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2979{
2980 struct ospf_packet *op;
2981 u_int16_t length = OSPF_HEADER_SIZE;
2982
2983 op = ospf_packet_new (oi->ifp->mtu);
2984
2985 /* Prepare OSPF common header. */
2986 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2987
2988 /* Prepare OSPF Hello body. */
2989 length += ospf_make_hello (oi, op->s);
2990
2991 /* Fill OSPF header. */
2992 ospf_fill_header (oi, op->s, length);
2993
2994 /* Set packet length. */
2995 op->length = length;
2996
2997 op->dst.s_addr = addr->s_addr;
2998
2999 /* Add packet to the interface output queue. */
3000 ospf_packet_add (oi, op);
3001
3002 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003003 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003004}
3005
3006void
3007ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3008{
3009 struct ospf_interface *oi;
3010
3011 oi = nbr_nbma->oi;
3012 assert(oi);
3013
3014 /* If this is passive interface, do not send OSPF Hello. */
3015 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3016 return;
3017
3018 if (oi->type != OSPF_IFTYPE_NBMA)
3019 return;
3020
3021 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3022 return;
3023
3024 if (PRIORITY(oi) == 0)
3025 return;
3026
3027 if (nbr_nbma->priority == 0
3028 && oi->state != ISM_DR && oi->state != ISM_Backup)
3029 return;
3030
3031 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3032}
3033
3034int
3035ospf_poll_timer (struct thread *thread)
3036{
3037 struct ospf_nbr_nbma *nbr_nbma;
3038
3039 nbr_nbma = THREAD_ARG (thread);
3040 nbr_nbma->t_poll = NULL;
3041
3042 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003043 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003044 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3045
3046 ospf_poll_send (nbr_nbma);
3047
3048 if (nbr_nbma->v_poll > 0)
3049 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3050 nbr_nbma->v_poll);
3051
3052 return 0;
3053}
3054
3055
3056int
3057ospf_hello_reply_timer (struct thread *thread)
3058{
3059 struct ospf_neighbor *nbr;
3060
3061 nbr = THREAD_ARG (thread);
3062 nbr->t_hello_reply = NULL;
3063
3064 assert (nbr->oi);
3065
3066 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003067 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003068 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3069
3070 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3071
3072 return 0;
3073}
3074
3075/* Send OSPF Hello. */
3076void
3077ospf_hello_send (struct ospf_interface *oi)
3078{
3079 struct ospf_packet *op;
3080 u_int16_t length = OSPF_HEADER_SIZE;
3081
3082 /* If this is passive interface, do not send OSPF Hello. */
3083 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3084 return;
3085
3086 op = ospf_packet_new (oi->ifp->mtu);
3087
3088 /* Prepare OSPF common header. */
3089 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3090
3091 /* Prepare OSPF Hello body. */
3092 length += ospf_make_hello (oi, op->s);
3093
3094 /* Fill OSPF header. */
3095 ospf_fill_header (oi, op->s, length);
3096
3097 /* Set packet length. */
3098 op->length = length;
3099
3100 if (oi->type == OSPF_IFTYPE_NBMA)
3101 {
3102 struct ospf_neighbor *nbr;
3103 struct route_node *rn;
3104
3105 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3106 if ((nbr = rn->info))
3107 if (nbr != oi->nbr_self)
3108 if (nbr->state != NSM_Down)
3109 {
3110 /* RFC 2328 Section 9.5.1
3111 If the router is not eligible to become Designated Router,
3112 it must periodically send Hello Packets to both the
3113 Designated Router and the Backup Designated Router (if they
3114 exist). */
3115 if (PRIORITY(oi) == 0 &&
3116 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3117 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3118 continue;
3119
3120 /* If the router is eligible to become Designated Router, it
3121 must periodically send Hello Packets to all neighbors that
3122 are also eligible. In addition, if the router is itself the
3123 Designated Router or Backup Designated Router, it must also
3124 send periodic Hello Packets to all other neighbors. */
3125
3126 if (nbr->priority == 0 && oi->state == ISM_DROther)
3127 continue;
3128 /* if oi->state == Waiting, send hello to all neighbors */
3129 {
3130 struct ospf_packet *op_dup;
3131
3132 op_dup = ospf_packet_dup(op);
3133 op_dup->dst = nbr->address.u.prefix4;
3134
3135 /* Add packet to the interface output queue. */
3136 ospf_packet_add (oi, op_dup);
3137
paul020709f2003-04-04 02:44:16 +00003138 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003139 }
3140
3141 }
3142 ospf_packet_free (op);
3143 }
3144 else
3145 {
3146 /* Decide destination address. */
3147 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3148 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3149 else
3150 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3151
3152 /* Add packet to the interface output queue. */
3153 ospf_packet_add (oi, op);
3154
3155 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003156 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003157 }
3158}
3159
3160/* Send OSPF Database Description. */
3161void
3162ospf_db_desc_send (struct ospf_neighbor *nbr)
3163{
3164 struct ospf_interface *oi;
3165 struct ospf_packet *op;
3166 u_int16_t length = OSPF_HEADER_SIZE;
3167
3168 oi = nbr->oi;
3169 op = ospf_packet_new (oi->ifp->mtu);
3170
3171 /* Prepare OSPF common header. */
3172 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3173
3174 /* Prepare OSPF Database Description body. */
3175 length += ospf_make_db_desc (oi, nbr, op->s);
3176
3177 /* Fill OSPF header. */
3178 ospf_fill_header (oi, op->s, length);
3179
3180 /* Set packet length. */
3181 op->length = length;
3182
3183 /* Decide destination address. */
3184 op->dst = nbr->address.u.prefix4;
3185
3186 /* Add packet to the interface output queue. */
3187 ospf_packet_add (oi, op);
3188
3189 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003190 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003191
3192 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3193 if (nbr->last_send)
3194 ospf_packet_free (nbr->last_send);
3195 nbr->last_send = ospf_packet_dup (op);
3196 gettimeofday (&nbr->last_send_ts, NULL);
3197}
3198
3199/* Re-send Database Description. */
3200void
3201ospf_db_desc_resend (struct ospf_neighbor *nbr)
3202{
3203 struct ospf_interface *oi;
3204
3205 oi = nbr->oi;
3206
3207 /* Add packet to the interface output queue. */
3208 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3209
3210 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003211 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003212}
3213
3214/* Send Link State Request. */
3215void
3216ospf_ls_req_send (struct ospf_neighbor *nbr)
3217{
3218 struct ospf_interface *oi;
3219 struct ospf_packet *op;
3220 u_int16_t length = OSPF_HEADER_SIZE;
3221
3222 oi = nbr->oi;
3223 op = ospf_packet_new (oi->ifp->mtu);
3224
3225 /* Prepare OSPF common header. */
3226 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3227
3228 /* Prepare OSPF Link State Request body. */
3229 length += ospf_make_ls_req (nbr, op->s);
3230 if (length == OSPF_HEADER_SIZE)
3231 {
3232 ospf_packet_free (op);
3233 return;
3234 }
3235
3236 /* Fill OSPF header. */
3237 ospf_fill_header (oi, op->s, length);
3238
3239 /* Set packet length. */
3240 op->length = length;
3241
3242 /* Decide destination address. */
3243 op->dst = nbr->address.u.prefix4;
3244
3245 /* Add packet to the interface output queue. */
3246 ospf_packet_add (oi, op);
3247
3248 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003249 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003250
3251 /* Add Link State Request Retransmission Timer. */
3252 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3253}
3254
3255/* Send Link State Update with an LSA. */
3256void
3257ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3258 int flag)
3259{
hasso52dc7ee2004-09-23 19:18:23 +00003260 struct list *update;
paul718e3742002-12-13 20:15:29 +00003261
3262 update = list_new ();
3263
3264 listnode_add (update, lsa);
3265 ospf_ls_upd_send (nbr, update, flag);
3266
3267 list_delete (update);
3268}
3269
paul68b73392004-09-12 14:21:37 +00003270/* Determine size for packet. Must be at least big enough to accomodate next
3271 * LSA on list, which may be bigger than MTU size.
3272 *
3273 * Return pointer to new ospf_packet
3274 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3275 * on packet sizes (in which case offending LSA is deleted from update list)
3276 */
3277static struct ospf_packet *
3278ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3279{
3280 struct ospf_lsa *lsa;
3281 struct listnode *ln;
3282 size_t size;
3283 static char warned = 0;
3284
3285 ln = listhead (update);
3286 lsa = getdata (ln);
3287 assert (lsa);
3288 assert (lsa->data);
3289
3290 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3291 > ospf_packet_max (oi))
3292 {
3293 if (!warned)
3294 {
3295 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3296 "will need to fragment. Not optimal. Try divide up"
3297 " your network with areas. Use 'debug ospf packet send'"
3298 " to see details, or look at 'show ip ospf database ..'");
3299 warned = 1;
3300 }
3301
3302 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003303 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003304 " %d bytes originated by %s, will be fragmented!",
3305 inet_ntoa (lsa->data->id),
3306 ntohs (lsa->data->length),
3307 inet_ntoa (lsa->data->adv_router));
3308
3309 /*
3310 * Allocate just enough to fit this LSA only, to avoid including other
3311 * LSAs in fragmented LSA Updates.
3312 */
3313 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3314 + OSPF_LS_UPD_MIN_SIZE;
3315 }
3316 else
3317 size = oi->ifp->mtu;
3318
gdt86f1fd92005-01-10 14:20:43 +00003319 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003320 if (size > OSPF_MAX_PACKET_SIZE)
3321 {
3322 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003323 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003324 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003325 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003326 (long int) size);
paul68b73392004-09-12 14:21:37 +00003327 list_delete_node (update, ln);
3328 return NULL;
3329 }
3330
3331 return ospf_packet_new (size);
3332}
3333
paul718e3742002-12-13 20:15:29 +00003334static void
hasso52dc7ee2004-09-23 19:18:23 +00003335ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003336 struct in_addr addr)
3337{
3338 struct ospf_packet *op;
3339 u_int16_t length = OSPF_HEADER_SIZE;
3340
3341 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003342 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003343
3344 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003345
3346 /* Prepare OSPF common header. */
3347 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3348
paul59ea14c2004-07-14 20:50:36 +00003349 /* Prepare OSPF Link State Update body.
3350 * Includes Type-7 translation.
3351 */
paul718e3742002-12-13 20:15:29 +00003352 length += ospf_make_ls_upd (oi, update, op->s);
3353
3354 /* Fill OSPF header. */
3355 ospf_fill_header (oi, op->s, length);
3356
3357 /* Set packet length. */
3358 op->length = length;
3359
3360 /* Decide destination address. */
3361 op->dst.s_addr = addr.s_addr;
3362
3363 /* Add packet to the interface output queue. */
3364 ospf_packet_add (oi, op);
3365
3366 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003367 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003368}
3369
3370static int
3371ospf_ls_upd_send_queue_event (struct thread *thread)
3372{
3373 struct ospf_interface *oi = THREAD_ARG(thread);
3374 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003375 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003376 struct list *update;
paul68b73392004-09-12 14:21:37 +00003377 char again = 0;
paul718e3742002-12-13 20:15:29 +00003378
3379 oi->t_ls_upd_event = NULL;
3380
3381 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003382 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003383
paul736d3442003-07-24 23:22:57 +00003384 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003385 {
paul736d3442003-07-24 23:22:57 +00003386 rnext = route_next (rn);
3387
paul718e3742002-12-13 20:15:29 +00003388 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003389 continue;
paul68b73392004-09-12 14:21:37 +00003390
3391 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003392
paul48fe13b2004-07-27 17:40:44 +00003393 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003394
paul68b73392004-09-12 14:21:37 +00003395 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003396 if (listcount(update) == 0)
3397 {
3398 list_delete (rn->info);
3399 rn->info = NULL;
3400 route_unlock_node (rn);
3401 }
3402 else
paul68b73392004-09-12 14:21:37 +00003403 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003404 }
3405
3406 if (again != 0)
3407 {
3408 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003409 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003410 " %d nodes to try again, raising new event", again);
3411 oi->t_ls_upd_event =
3412 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003413 }
3414
3415 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003416 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003417
paul718e3742002-12-13 20:15:29 +00003418 return 0;
3419}
3420
3421void
hasso52dc7ee2004-09-23 19:18:23 +00003422ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003423{
3424 struct ospf_interface *oi;
3425 struct prefix_ipv4 p;
3426 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003427 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003428
3429 oi = nbr->oi;
3430
3431 p.family = AF_INET;
3432 p.prefixlen = IPV4_MAX_BITLEN;
3433
3434 /* Decide destination address. */
3435 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3436 p.prefix = oi->vl_data->peer_addr;
3437 else if (flag == OSPF_SEND_PACKET_DIRECT)
3438 p.prefix = nbr->address.u.prefix4;
3439 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3440 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3441 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3442 && (flag == OSPF_SEND_PACKET_INDIRECT))
3443 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003444 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3445 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003446 else
3447 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3448
3449 if (oi->type == OSPF_IFTYPE_NBMA)
3450 {
3451 if (flag == OSPF_SEND_PACKET_INDIRECT)
3452 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3453 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3454 zlog_warn ("* LS-Update is sent to myself.");
3455 }
3456
3457 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3458
3459 if (rn->info == NULL)
3460 rn->info = list_new ();
3461
3462 for (n = listhead (update); n; nextnode (n))
3463 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3464
3465 if (oi->t_ls_upd_event == NULL)
3466 oi->t_ls_upd_event =
3467 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3468}
3469
3470static void
hasso52dc7ee2004-09-23 19:18:23 +00003471ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3472 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003473{
3474 struct ospf_packet *op;
3475 u_int16_t length = OSPF_HEADER_SIZE;
3476
3477 op = ospf_packet_new (oi->ifp->mtu);
3478
3479 /* Prepare OSPF common header. */
3480 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3481
3482 /* Prepare OSPF Link State Acknowledgment body. */
3483 length += ospf_make_ls_ack (oi, ack, op->s);
3484
3485 /* Fill OSPF header. */
3486 ospf_fill_header (oi, op->s, length);
3487
3488 /* Set packet length. */
3489 op->length = length;
3490
3491 /* Set destination IP address. */
3492 op->dst = dst;
3493
3494 /* Add packet to the interface output queue. */
3495 ospf_packet_add (oi, op);
3496
3497 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003498 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003499}
3500
3501static int
3502ospf_ls_ack_send_event (struct thread *thread)
3503{
3504 struct ospf_interface *oi = THREAD_ARG (thread);
3505
3506 oi->t_ls_ack_direct = NULL;
3507
3508 while (listcount (oi->ls_ack_direct.ls_ack))
3509 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3510 oi->ls_ack_direct.dst);
3511
3512 return 0;
3513}
3514
3515void
3516ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3517{
3518 struct ospf_interface *oi = nbr->oi;
3519
3520 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3521 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3522
3523 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3524
3525 if (oi->t_ls_ack_direct == NULL)
3526 oi->t_ls_ack_direct =
3527 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3528}
3529
3530/* Send Link State Acknowledgment delayed. */
3531void
3532ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3533{
3534 struct in_addr dst;
3535
3536 /* Decide destination address. */
3537 /* RFC2328 Section 13.5 On non-broadcast
3538 networks, delayed Link State Acknowledgment packets must be
3539 unicast separately over each adjacency (i.e., neighbor whose
3540 state is >= Exchange). */
3541 if (oi->type == OSPF_IFTYPE_NBMA)
3542 {
3543 struct ospf_neighbor *nbr;
3544 struct route_node *rn;
3545
3546 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3547 if ((nbr = rn->info) != NULL)
3548 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3549 while (listcount (oi->ls_ack))
3550 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3551 return;
3552 }
3553 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3554 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3555 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3556 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3557 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3558 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003559 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3560 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003561 else
3562 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3563
3564 while (listcount (oi->ls_ack))
3565 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3566}