blob: 15ec37338d64bbabdc4882c10f8e0e234aeae507 [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"
paul484315f2005-11-03 09:08:29 +000035#include "checksum.h"
vincentc1a03d42005-09-28 15:47:44 +000036#include "md5.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_network.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_lsdb.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_spf.h"
49#include "ospfd/ospf_flood.h"
50#include "ospfd/ospf_dump.h"
51
paul718e3742002-12-13 20:15:29 +000052/* Packet Type String. */
Denis Ovsienko272ca1e2012-01-15 19:12:19 +040053const struct message ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000054{
Denis Ovsienko272ca1e2012-01-15 19:12:19 +040055 { OSPF_MSG_HELLO, "Hello" },
56 { OSPF_MSG_DB_DESC, "Database Description" },
57 { OSPF_MSG_LS_REQ, "Link State Request" },
58 { OSPF_MSG_LS_UPD, "Link State Update" },
59 { OSPF_MSG_LS_ACK, "Link State Acknowledgment" },
paul718e3742002-12-13 20:15:29 +000060};
Denis Ovsienko272ca1e2012-01-15 19:12:19 +040061const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
62 sizeof (ospf_packet_type_str[0]);
paul718e3742002-12-13 20:15:29 +000063
Denis Ovsienko75c8eab2012-01-30 15:41:39 +040064/* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
65 particular types, offset is the "type" field of a packet. */
66static const u_int16_t ospf_packet_minlen[] =
67{
68 0,
69 OSPF_HELLO_MIN_SIZE,
70 OSPF_DB_DESC_MIN_SIZE,
71 OSPF_LS_REQ_MIN_SIZE,
72 OSPF_LS_UPD_MIN_SIZE,
73 OSPF_LS_ACK_MIN_SIZE,
74};
75
paul718e3742002-12-13 20:15:29 +000076/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000077static int
paul718e3742002-12-13 20:15:29 +000078ospf_auth_type (struct ospf_interface *oi)
79{
80 int auth_type;
81
82 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
83 auth_type = oi->area->auth_type;
84 else
85 auth_type = OSPF_IF_PARAM (oi, auth_type);
86
87 /* Handle case where MD5 key list is not configured aka Cisco */
88 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
89 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
90 return OSPF_AUTH_NULL;
91
92 return auth_type;
93
94}
95
paul718e3742002-12-13 20:15:29 +000096struct ospf_packet *
97ospf_packet_new (size_t size)
98{
99 struct ospf_packet *new;
100
101 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
102 new->s = stream_new (size);
103
104 return new;
105}
106
107void
108ospf_packet_free (struct ospf_packet *op)
109{
110 if (op->s)
111 stream_free (op->s);
112
113 XFREE (MTYPE_OSPF_PACKET, op);
114
115 op = NULL;
116}
117
118struct ospf_fifo *
119ospf_fifo_new ()
120{
121 struct ospf_fifo *new;
122
123 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
124 return new;
125}
126
127/* Add new packet to fifo. */
128void
129ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
130{
131 if (fifo->tail)
132 fifo->tail->next = op;
133 else
134 fifo->head = op;
135
136 fifo->tail = op;
137
138 fifo->count++;
139}
140
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000141/* Add new packet to head of fifo. */
142static void
143ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
144{
145 op->next = fifo->head;
146
147 if (fifo->tail == NULL)
148 fifo->tail = op;
149
150 fifo->head = op;
151
152 fifo->count++;
153}
154
paul718e3742002-12-13 20:15:29 +0000155/* Delete first packet from fifo. */
156struct ospf_packet *
157ospf_fifo_pop (struct ospf_fifo *fifo)
158{
159 struct ospf_packet *op;
160
161 op = fifo->head;
162
163 if (op)
164 {
165 fifo->head = op->next;
166
167 if (fifo->head == NULL)
168 fifo->tail = NULL;
169
170 fifo->count--;
171 }
172
173 return op;
174}
175
176/* Return first fifo entry. */
177struct ospf_packet *
178ospf_fifo_head (struct ospf_fifo *fifo)
179{
180 return fifo->head;
181}
182
183/* Flush ospf packet fifo. */
184void
185ospf_fifo_flush (struct ospf_fifo *fifo)
186{
187 struct ospf_packet *op;
188 struct ospf_packet *next;
189
190 for (op = fifo->head; op; op = next)
191 {
192 next = op->next;
193 ospf_packet_free (op);
194 }
195 fifo->head = fifo->tail = NULL;
196 fifo->count = 0;
197}
198
199/* Free ospf packet fifo. */
200void
201ospf_fifo_free (struct ospf_fifo *fifo)
202{
203 ospf_fifo_flush (fifo);
204
205 XFREE (MTYPE_OSPF_FIFO, fifo);
206}
207
208void
209ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
210{
ajsc3eab872005-01-29 15:52:07 +0000211 if (!oi->obuf)
212 {
213 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
214 "destination %s) called with NULL obuf, ignoring "
215 "(please report this bug)!\n",
216 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400217 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
ajsc3eab872005-01-29 15:52:07 +0000218 inet_ntoa (op->dst));
219 return;
220 }
221
paul718e3742002-12-13 20:15:29 +0000222 /* Add packet to end of queue. */
223 ospf_fifo_push (oi->obuf, op);
224
225 /* Debug of packet fifo*/
226 /* ospf_fifo_debug (oi->obuf); */
227}
228
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000229static void
230ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
231{
232 if (!oi->obuf)
233 {
234 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
235 "destination %s) called with NULL obuf, ignoring "
236 "(please report this bug)!\n",
237 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
Denis Ovsienko7e0e2cb2012-01-20 22:32:10 +0400238 LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
Paul Jakmaaa276fd2010-01-08 17:11:15 +0000239 inet_ntoa (op->dst));
240 return;
241 }
242
243 /* Add packet to head of queue. */
244 ospf_fifo_push_head (oi->obuf, op);
245
246 /* Debug of packet fifo*/
247 /* ospf_fifo_debug (oi->obuf); */
248}
249
paul718e3742002-12-13 20:15:29 +0000250void
251ospf_packet_delete (struct ospf_interface *oi)
252{
253 struct ospf_packet *op;
254
255 op = ospf_fifo_pop (oi->obuf);
256
257 if (op)
258 ospf_packet_free (op);
259}
260
paul718e3742002-12-13 20:15:29 +0000261struct ospf_packet *
262ospf_packet_dup (struct ospf_packet *op)
263{
264 struct ospf_packet *new;
265
paul37163d62003-02-03 18:40:56 +0000266 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000267 /* XXX size_t */
268 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
269 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000270
271 /* Reserve space for MD5 authentication that may be added later. */
272 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000273 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000274
275 new->dst = op->dst;
276 new->length = op->length;
277
278 return new;
279}
280
gdt86f1fd92005-01-10 14:20:43 +0000281/* XXX inline */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100282static unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000283ospf_packet_authspace (struct ospf_interface *oi)
284{
285 int auth = 0;
286
287 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
288 auth = OSPF_AUTH_MD5_SIZE;
289
290 return auth;
291}
292
paul4dadc292005-05-06 21:37:42 +0000293static unsigned int
paul718e3742002-12-13 20:15:29 +0000294ospf_packet_max (struct ospf_interface *oi)
295{
296 int max;
297
gdt86f1fd92005-01-10 14:20:43 +0000298 max = oi->ifp->mtu - ospf_packet_authspace(oi);
299
paul68b73392004-09-12 14:21:37 +0000300 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000301
302 return max;
303}
304
305
paul4dadc292005-05-06 21:37:42 +0000306static int
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400307ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +0000308{
vincentc1a03d42005-09-28 15:47:44 +0000309 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000310 unsigned char digest[OSPF_AUTH_MD5_SIZE];
paul718e3742002-12-13 20:15:29 +0000311 struct crypt_key *ck;
paul718e3742002-12-13 20:15:29 +0000312 struct ospf_neighbor *nbr;
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400313 u_int16_t length = ntohs (ospfh->length);
paul718e3742002-12-13 20:15:29 +0000314
paul718e3742002-12-13 20:15:29 +0000315 /* Get secret key. */
316 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
317 ospfh->u.crypt.key_id);
318 if (ck == NULL)
319 {
320 zlog_warn ("interface %s: ospf_check_md5 no key %d",
321 IF_NAME (oi), ospfh->u.crypt.key_id);
322 return 0;
323 }
324
325 /* check crypto seqnum. */
326 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
327
328 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
329 {
330 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
331 IF_NAME (oi),
332 ntohl(ospfh->u.crypt.crypt_seqnum),
333 ntohl(nbr->crypt_seqnum));
334 return 0;
335 }
336
337 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000338 memset(&ctx, 0, sizeof(ctx));
339 MD5Init(&ctx);
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400340 MD5Update(&ctx, ospfh, length);
vincentc1a03d42005-09-28 15:47:44 +0000341 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
342 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000343
344 /* compare the two */
Denis Ovsienko2d8223c2012-01-30 20:32:39 +0400345 if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
paul718e3742002-12-13 20:15:29 +0000346 {
347 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
348 IF_NAME (oi));
349 return 0;
350 }
351
352 /* save neighbor's crypt_seqnum */
353 if (nbr)
354 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
355 return 1;
356}
357
358/* This function is called from ospf_write(), it will detect the
359 authentication scheme and if it is MD5, it will change the sequence
360 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000361static int
paul718e3742002-12-13 20:15:29 +0000362ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
363{
364 struct ospf_header *ospfh;
365 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000366 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000367 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000368 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000369 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000370 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000371
372 ibuf = STREAM_DATA (op->s);
373 ospfh = (struct ospf_header *) ibuf;
374
375 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
376 return 0;
377
378 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000379 waste CPU rewriting other headers.
380
381 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000382 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000383 if (t > oi->crypt_seqnum)
384 oi->crypt_seqnum = t;
385 else
386 oi->crypt_seqnum++;
387
paul9483e152002-12-13 20:55:25 +0000388 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000389
390 /* Get MD5 Authentication key from auth_key list. */
391 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000392 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000393 else
394 {
paul1eb8ef22005-04-07 07:30:20 +0000395 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000396 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000397 }
398
399 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000400 memset(&ctx, 0, sizeof(ctx));
401 MD5Init(&ctx);
402 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
403 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
404 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000405
406 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000407 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000408
409 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000410 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
411
paul37163d62003-02-03 18:40:56 +0000412 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000413 /* XXX size_t */
414 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
415 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000416
417 return OSPF_AUTH_MD5_SIZE;
418}
419
420
paul4dadc292005-05-06 21:37:42 +0000421static int
paul718e3742002-12-13 20:15:29 +0000422ospf_ls_req_timer (struct thread *thread)
423{
424 struct ospf_neighbor *nbr;
425
426 nbr = THREAD_ARG (thread);
427 nbr->t_ls_req = NULL;
428
429 /* Send Link State Request. */
430 if (ospf_ls_request_count (nbr))
431 ospf_ls_req_send (nbr);
432
433 /* Set Link State Request retransmission timer. */
434 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
435
436 return 0;
437}
438
439void
440ospf_ls_req_event (struct ospf_neighbor *nbr)
441{
442 if (nbr->t_ls_req)
443 {
444 thread_cancel (nbr->t_ls_req);
445 nbr->t_ls_req = NULL;
446 }
447 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
448}
449
450/* Cyclic timer function. Fist registered in ospf_nbr_new () in
451 ospf_neighbor.c */
452int
453ospf_ls_upd_timer (struct thread *thread)
454{
455 struct ospf_neighbor *nbr;
456
457 nbr = THREAD_ARG (thread);
458 nbr->t_ls_upd = NULL;
459
460 /* Send Link State Update. */
461 if (ospf_ls_retransmit_count (nbr) > 0)
462 {
hasso52dc7ee2004-09-23 19:18:23 +0000463 struct list *update;
paul718e3742002-12-13 20:15:29 +0000464 struct ospf_lsdb *lsdb;
465 int i;
paul718e3742002-12-13 20:15:29 +0000466 int retransmit_interval;
467
paul718e3742002-12-13 20:15:29 +0000468 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
469
470 lsdb = &nbr->ls_rxmt;
471 update = list_new ();
472
473 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
474 {
475 struct route_table *table = lsdb->type[i].db;
476 struct route_node *rn;
477
478 for (rn = route_top (table); rn; rn = route_next (rn))
479 {
480 struct ospf_lsa *lsa;
481
482 if ((lsa = rn->info) != NULL)
483 /* Don't retransmit an LSA if we received it within
484 the last RxmtInterval seconds - this is to allow the
485 neighbour a chance to acknowledge the LSA as it may
486 have ben just received before the retransmit timer
487 fired. This is a small tweak to what is in the RFC,
488 but it will cut out out a lot of retransmit traffic
489 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000490 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000491 int2tv (retransmit_interval)) >= 0)
492 listnode_add (update, rn->info);
493 }
494 }
495
496 if (listcount (update) > 0)
497 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
498 list_delete (update);
499 }
500
501 /* Set LS Update retransmission timer. */
502 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
503
504 return 0;
505}
506
507int
508ospf_ls_ack_timer (struct thread *thread)
509{
510 struct ospf_interface *oi;
511
512 oi = THREAD_ARG (thread);
513 oi->t_ls_ack = NULL;
514
515 /* Send Link State Acknowledgment. */
516 if (listcount (oi->ls_ack) > 0)
517 ospf_ls_ack_send_delayed (oi);
518
519 /* Set LS Ack timer. */
520 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
521
522 return 0;
523}
524
paul0bfeca32004-09-24 08:07:54 +0000525#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000526static void
paul6a99f832004-09-27 12:56:30 +0000527ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000528 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000529 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000530{
531#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000532 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000533 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000534 int ret;
paul0bfeca32004-09-24 08:07:54 +0000535
536 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000537 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000538
539 /* we can but try.
540 *
541 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
542 * well as the IP_MF flag, making this all quite pointless.
543 *
544 * However, for a system on which IP_MF is left alone, and ip_id left
545 * alone or else which sets same ip_id for each fragment this might
546 * work, eg linux.
547 *
548 * XXX-TODO: It would be much nicer to have the kernel's use their
549 * existing fragmentation support to do this for us. Bugs/RFEs need to
550 * be raised against the various kernels.
551 */
552
553 /* set More Frag */
554 iph->ip_off |= IP_MF;
555
556 /* ip frag offset is expressed in units of 8byte words */
557 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
558
paul62d8e962004-11-02 20:26:45 +0000559 iovp = &msg->msg_iov[1];
560
paul0bfeca32004-09-24 08:07:54 +0000561 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
562 > maxdatasize )
563 {
564 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000565 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
566 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000567 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000568
paul18b12c32004-10-05 14:38:29 +0000569 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000570
paul6a99f832004-09-27 12:56:30 +0000571 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000572
paul18b12c32004-10-05 14:38:29 +0000573 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000574
575 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000576 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000577 " id %d, off %d, len %d, mtu %u failed with %s",
578 inet_ntoa (iph->ip_dst),
579 iph->ip_id,
580 iph->ip_off,
581 iph->ip_len,
582 mtu,
583 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000584
paul37ccfa32004-10-31 11:24:51 +0000585 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
586 {
ajs2a42e282004-12-08 18:43:03 +0000587 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000588 iph->ip_id, iph->ip_off, iph->ip_len,
589 inet_ntoa (iph->ip_dst));
590 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
591 {
ajs2a42e282004-12-08 18:43:03 +0000592 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000593 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000594 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000595 }
596 }
597
paul0bfeca32004-09-24 08:07:54 +0000598 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000599 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000600 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000601 }
602
603 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000604 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
605 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000606 iph->ip_off &= (~IP_MF);
607}
608#endif /* WANT_OSPF_WRITE_FRAGMENT */
609
ajs5dcbdf82005-03-29 16:13:49 +0000610static int
paul718e3742002-12-13 20:15:29 +0000611ospf_write (struct thread *thread)
612{
paul68980082003-03-25 05:07:42 +0000613 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000614 struct ospf_interface *oi;
615 struct ospf_packet *op;
616 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000617 struct ip iph;
618 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000619 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000620 u_char type;
621 int ret;
622 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000623 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000624#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000625 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000626#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000627 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000628#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000629
paul68980082003-03-25 05:07:42 +0000630 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000631
paul68980082003-03-25 05:07:42 +0000632 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000633 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000634 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000635 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000636
637#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000638 /* seed ipid static with low order bits of time */
639 if (ipid == 0)
640 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000641#endif /* WANT_OSPF_WRITE_FRAGMENT */
642
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000643 /* convenience - max OSPF data per packet,
644 * and reliability - not more data, than our
645 * socket can accept
646 */
647 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
648 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000649
paul718e3742002-12-13 20:15:29 +0000650 /* Get one packet from queue. */
651 op = ospf_fifo_head (oi->obuf);
652 assert (op);
653 assert (op->length >= OSPF_HEADER_SIZE);
654
paul68980082003-03-25 05:07:42 +0000655 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
656 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000657 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
658
paul718e3742002-12-13 20:15:29 +0000659 /* Rewrite the md5 signature & update the seq */
660 ospf_make_md5_digest (oi, op);
661
paul37ccfa32004-10-31 11:24:51 +0000662 /* Retrieve OSPF packet type. */
663 stream_set_getp (op->s, 1);
664 type = stream_getc (op->s);
665
paul68b73392004-09-12 14:21:37 +0000666 /* reset get pointer */
667 stream_set_getp (op->s, 0);
668
669 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000670 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000671
paul718e3742002-12-13 20:15:29 +0000672 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000673#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000674 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000675#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000676 sa_dst.sin_addr = op->dst;
677 sa_dst.sin_port = htons (0);
678
679 /* Set DONTROUTE flag if dst is unicast. */
680 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
681 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
682 flags = MSG_DONTROUTE;
683
paul68b73392004-09-12 14:21:37 +0000684 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
685 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000686 if ( sizeof (struct ip)
687 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000688 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
689
paul718e3742002-12-13 20:15:29 +0000690 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000691 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000692 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000693
David BÉRARD0150c9c2010-05-11 10:17:53 +0200694#if defined(__DragonFly__)
695 /*
696 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
697 */
698 iph.ip_len = htons(iph.ip_len);
699#endif
700
paul0bfeca32004-09-24 08:07:54 +0000701#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000702 /* XXX-MT: not thread-safe at all..
703 * XXX: this presumes this is only programme sending OSPF packets
704 * otherwise, no guarantee ipid will be unique
705 */
706 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000707#endif /* WANT_OSPF_WRITE_FRAGMENT */
708
paul718e3742002-12-13 20:15:29 +0000709 iph.ip_off = 0;
710 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
711 iph.ip_ttl = OSPF_VL_IP_TTL;
712 else
713 iph.ip_ttl = OSPF_IP_TTL;
714 iph.ip_p = IPPROTO_OSPFIGP;
715 iph.ip_sum = 0;
716 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
717 iph.ip_dst.s_addr = op->dst.s_addr;
718
719 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000720 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000721 msg.msg_namelen = sizeof (sa_dst);
722 msg.msg_iov = iov;
723 msg.msg_iovlen = 2;
724 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000725 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
726 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000727 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000728
729 /* Sadly we can not rely on kernels to fragment packets because of either
730 * IP_HDRINCL and/or multicast destination being set.
731 */
paul0bfeca32004-09-24 08:07:54 +0000732#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000733 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000734 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
735 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000736#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000737
738 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000739 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000740 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000741 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000742
743 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000744 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000745 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000746 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000747 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000748
paul718e3742002-12-13 20:15:29 +0000749 /* Show debug sending packet. */
750 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
751 {
752 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
753 {
ajs2a42e282004-12-08 18:43:03 +0000754 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000755 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000756 stream_set_getp (op->s, 0);
757 ospf_packet_dump (op->s);
758 }
759
ajs2a42e282004-12-08 18:43:03 +0000760 zlog_debug ("%s sent to [%s] via [%s].",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400761 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
paul718e3742002-12-13 20:15:29 +0000762 IF_NAME (oi));
763
764 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000765 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000766 }
767
768 /* Now delete packet from queue. */
769 ospf_packet_delete (oi);
770
771 if (ospf_fifo_head (oi->obuf) == NULL)
772 {
773 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000774 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000775 }
776
777 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000778 if (!list_isempty (ospf->oi_write_q))
779 ospf->t_write =
780 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000781
782 return 0;
783}
784
785/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000786static void
paul718e3742002-12-13 20:15:29 +0000787ospf_hello (struct ip *iph, struct ospf_header *ospfh,
788 struct stream * s, struct ospf_interface *oi, int size)
789{
790 struct ospf_hello *hello;
791 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000792 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000793 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000794
795 /* increment statistics. */
796 oi->hello_in++;
797
798 hello = (struct ospf_hello *) STREAM_PNT (s);
799
800 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000801 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000802 {
803 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
804 {
ajs2a42e282004-12-08 18:43:03 +0000805 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000806 "dropping.",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +0400807 LOOKUP (ospf_packet_type_str, ospfh->type),
pauld3241812003-09-29 12:42:39 +0000808 inet_ntoa (iph->ip_src));
809 }
810 return;
811 }
paul718e3742002-12-13 20:15:29 +0000812
paul718e3742002-12-13 20:15:29 +0000813 /* get neighbor prefix. */
814 p.family = AF_INET;
815 p.prefixlen = ip_masklen (hello->network_mask);
816 p.u.prefix4 = iph->ip_src;
817
818 /* Compare network mask. */
819 /* Checking is ignored for Point-to-Point and Virtual link. */
820 if (oi->type != OSPF_IFTYPE_POINTOPOINT
821 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
822 if (oi->address->prefixlen != p.prefixlen)
823 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000824 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
825 inet_ntoa(ospfh->router_id), IF_NAME(oi),
826 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000827 return;
828 }
829
paul718e3742002-12-13 20:15:29 +0000830 /* Compare Router Dead Interval. */
831 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
832 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000833 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
834 "(expected %u, but received %u).",
835 inet_ntoa(ospfh->router_id),
836 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000837 return;
838 }
839
paulf9ad9372005-10-21 00:45:17 +0000840 /* Compare Hello Interval - ignored if fast-hellos are set. */
841 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
842 {
843 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
844 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000845 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
846 "(expected %u, but received %u).",
847 inet_ntoa(ospfh->router_id),
848 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000849 return;
850 }
851 }
852
paul718e3742002-12-13 20:15:29 +0000853 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000854 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000855 inet_ntoa (ospfh->router_id),
856 ospf_options_dump (hello->options));
857
858 /* Compare options. */
859#define REJECT_IF_TBIT_ON 1 /* XXX */
860#ifdef REJECT_IF_TBIT_ON
861 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
862 {
863 /*
864 * This router does not support non-zero TOS.
865 * Drop this Hello packet not to establish neighbor relationship.
866 */
867 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
868 inet_ntoa (ospfh->router_id));
869 return;
870 }
871#endif /* REJECT_IF_TBIT_ON */
872
873#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000874 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000875 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
876 {
877 /*
878 * This router does know the correct usage of O-bit
879 * the bit should be set in DD packet only.
880 */
881 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
882 inet_ntoa (ospfh->router_id));
883#ifdef STRICT_OBIT_USAGE_CHECK
884 return; /* Reject this packet. */
885#else /* STRICT_OBIT_USAGE_CHECK */
886 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
887#endif /* STRICT_OBIT_USAGE_CHECK */
888 }
889#endif /* HAVE_OPAQUE_LSA */
890
891 /* new for NSSA is to ensure that NP is on and E is off */
892
paul718e3742002-12-13 20:15:29 +0000893 if (oi->area->external_routing == OSPF_AREA_NSSA)
894 {
895 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
896 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
897 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
898 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
899 {
900 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
901 return;
902 }
903 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000904 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000905 }
906 else
paul718e3742002-12-13 20:15:29 +0000907 /* The setting of the E-bit found in the Hello Packet's Options
908 field must match this area's ExternalRoutingCapability A
909 mismatch causes processing to stop and the packet to be
910 dropped. The setting of the rest of the bits in the Hello
911 Packet's Options field should be ignored. */
912 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
913 CHECK_FLAG (hello->options, OSPF_OPTION_E))
914 {
ajs3aa8d5f2004-12-11 18:00:06 +0000915 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
916 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000917 return;
918 }
paul718e3742002-12-13 20:15:29 +0000919
pauld3f0d622004-05-05 15:27:15 +0000920 /* get neighbour struct */
921 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
922
923 /* neighbour must be valid, ospf_nbr_get creates if none existed */
924 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000925
926 old_state = nbr->state;
927
928 /* Add event to thread. */
Paul Jakma57c5c652010-01-07 06:12:53 +0000929 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
paul718e3742002-12-13 20:15:29 +0000930
931 /* RFC2328 Section 9.5.1
932 If the router is not eligible to become Designated Router,
933 (snip) It must also send an Hello Packet in reply to an
934 Hello Packet received from any eligible neighbor (other than
935 the current Designated Router and Backup Designated Router). */
936 if (oi->type == OSPF_IFTYPE_NBMA)
937 if (PRIORITY(oi) == 0 && hello->priority > 0
938 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
939 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
940 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
941 OSPF_HELLO_REPLY_DELAY);
942
943 /* on NBMA network type, it happens to receive bidirectional Hello packet
944 without advance 1-Way Received event.
945 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
946 if (oi->type == OSPF_IFTYPE_NBMA &&
947 (old_state == NSM_Down || old_state == NSM_Attempt))
948 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000949 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000950 nbr->priority = hello->priority;
951 nbr->d_router = hello->d_router;
952 nbr->bd_router = hello->bd_router;
953 return;
954 }
955
paul68980082003-03-25 05:07:42 +0000956 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000957 size - OSPF_HELLO_MIN_SIZE))
958 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000959 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
paul718e3742002-12-13 20:15:29 +0000960 nbr->options |= hello->options;
961 }
962 else
963 {
Paul Jakma57c5c652010-01-07 06:12:53 +0000964 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
paul718e3742002-12-13 20:15:29 +0000965 /* Set neighbor information. */
966 nbr->priority = hello->priority;
967 nbr->d_router = hello->d_router;
968 nbr->bd_router = hello->bd_router;
969 return;
970 }
971
972 /* If neighbor itself declares DR and no BDR exists,
973 cause event BackupSeen */
974 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
975 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
976 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
977
978 /* neighbor itself declares BDR. */
979 if (oi->state == ISM_Waiting &&
980 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
981 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
982
983 /* had not previously. */
984 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
985 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
986 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
987 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
988 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
989
990 /* had not previously. */
991 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
992 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
993 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
994 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
995 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
996
997 /* Neighbor priority check. */
998 if (nbr->priority >= 0 && nbr->priority != hello->priority)
999 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1000
1001 /* Set neighbor information. */
1002 nbr->priority = hello->priority;
1003 nbr->d_router = hello->d_router;
1004 nbr->bd_router = hello->bd_router;
1005}
1006
1007/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +00001008static void
paul718e3742002-12-13 20:15:29 +00001009ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1010 struct ospf_db_desc *dd)
1011{
1012 nbr->last_recv.flags = dd->flags;
1013 nbr->last_recv.options = dd->options;
1014 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1015}
1016
1017/* Process rest of DD packet. */
1018static void
1019ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1020 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1021 u_int16_t size)
1022{
1023 struct ospf_lsa *new, *find;
1024 struct lsa_header *lsah;
1025
paul9985f832005-02-09 15:51:56 +00001026 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00001027 for (size -= OSPF_DB_DESC_MIN_SIZE;
1028 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1029 {
1030 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001031 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001032
1033 /* Unknown LS type. */
1034 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1035 {
ajsbec595a2004-11-30 22:38:43 +00001036 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001037 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1038 return;
1039 }
1040
1041#ifdef HAVE_OPAQUE_LSA
1042 if (IS_OPAQUE_LSA (lsah->type)
1043 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1044 {
1045 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1046 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1047 return;
1048 }
1049#endif /* HAVE_OPAQUE_LSA */
1050
1051 switch (lsah->type)
1052 {
1053 case OSPF_AS_EXTERNAL_LSA:
1054#ifdef HAVE_OPAQUE_LSA
1055 case OSPF_OPAQUE_AS_LSA:
1056#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001057 /* Check for stub area. Reject if AS-External from stub but
1058 allow if from NSSA. */
1059 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001060 {
1061 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1062 lsah->type, inet_ntoa (lsah->id),
1063 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1064 "STUB" : "NSSA");
1065 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1066 return;
1067 }
1068 break;
1069 default:
1070 break;
1071 }
1072
1073 /* Create LS-request object. */
1074 new = ospf_ls_request_new (lsah);
1075
1076 /* Lookup received LSA, then add LS request list. */
1077 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001078
1079 /* ospf_lsa_more_recent is fine with NULL pointers */
1080 switch (ospf_lsa_more_recent (find, new))
1081 {
1082 case -1:
1083 /* Neighbour has a more recent LSA, we must request it */
1084 ospf_ls_request_add (nbr, new);
1085 case 0:
1086 /* If we have a copy of this LSA, it's either less recent
1087 * and we're requesting it from neighbour (the case above), or
1088 * it's as recent and we both have same copy (this case).
1089 *
1090 * In neither of these two cases is there any point in
1091 * describing our copy of the LSA to the neighbour in a
1092 * DB-Summary packet, if we're still intending to do so.
1093 *
1094 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1095 * backward compatible optimisation to OSPF DB Exchange /
1096 * DB Description process implemented here.
1097 */
1098 if (find)
1099 ospf_lsdb_delete (&nbr->db_sum, find);
1100 ospf_lsa_discard (new);
1101 break;
1102 default:
1103 /* We have the more recent copy, nothing specific to do:
1104 * - no need to request neighbours stale copy
1105 * - must leave DB summary list copy alone
1106 */
1107 if (IS_DEBUG_OSPF_EVENT)
1108 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1109 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1110 ospf_lsa_discard (new);
1111 }
paul718e3742002-12-13 20:15:29 +00001112 }
1113
1114 /* Master */
1115 if (IS_SET_DD_MS (nbr->dd_flags))
1116 {
1117 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001118
1119 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001120 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1121 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1122 else
paul718e3742002-12-13 20:15:29 +00001123 ospf_db_desc_send (nbr);
1124 }
1125 /* Slave */
1126 else
1127 {
1128 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1129
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001130 /* Send DD packet in reply.
1131 *
1132 * Must be done to acknowledge the Master's DD, regardless of
1133 * whether we have more LSAs ourselves to describe.
1134 *
1135 * This function will clear the 'More' bit, if after this DD
1136 * we have no more LSAs to describe to the master..
1137 */
paul718e3742002-12-13 20:15:29 +00001138 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001139
1140 /* Slave can raise ExchangeDone now, if master is also done */
1141 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1142 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001143 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001144
paul718e3742002-12-13 20:15:29 +00001145 /* Save received neighbor values from DD. */
1146 ospf_db_desc_save_current (nbr, dd);
1147}
1148
paul4dadc292005-05-06 21:37:42 +00001149static int
paul718e3742002-12-13 20:15:29 +00001150ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1151{
1152 /* Is DD duplicated? */
1153 if (dd->options == nbr->last_recv.options &&
1154 dd->flags == nbr->last_recv.flags &&
1155 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1156 return 1;
1157
1158 return 0;
1159}
1160
1161/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001162static void
paul718e3742002-12-13 20:15:29 +00001163ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1164 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1165{
1166 struct ospf_db_desc *dd;
1167 struct ospf_neighbor *nbr;
1168
1169 /* Increment statistics. */
1170 oi->db_desc_in++;
1171
1172 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001173
pauld3f0d622004-05-05 15:27:15 +00001174 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001175 if (nbr == NULL)
1176 {
1177 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1178 inet_ntoa (ospfh->router_id));
1179 return;
1180 }
1181
1182 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001183 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1184 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001185 {
ajs3aa8d5f2004-12-11 18:00:06 +00001186 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1187 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1188 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001189 return;
1190 }
1191
pauld363df22003-06-19 00:26:34 +00001192 /*
1193 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1194 * required. In fact at least JunOS sends DD packets with P bit clear.
1195 * Until proper solution is developped, this hack should help.
1196 *
1197 * Update: According to the RFCs, N bit is specified /only/ for Hello
1198 * options, unfortunately its use in DD options is not specified. Hence some
1199 * implementations follow E-bit semantics and set it in DD options, and some
1200 * treat it as unspecified and hence follow the directive "default for
1201 * options is clear", ie unset.
1202 *
1203 * Reset the flag, as ospfd follows E-bit semantics.
1204 */
1205 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1206 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1207 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1208 {
1209 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001210 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001211 inet_ntoa (nbr->router_id) );
1212 SET_FLAG (dd->options, OSPF_OPTION_NP);
1213 }
pauld363df22003-06-19 00:26:34 +00001214
paul718e3742002-12-13 20:15:29 +00001215#ifdef REJECT_IF_TBIT_ON
1216 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1217 {
1218 /*
1219 * In Hello protocol, optional capability must have checked
1220 * to prevent this T-bit enabled router be my neighbor.
1221 */
1222 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1223 return;
1224 }
1225#endif /* REJECT_IF_TBIT_ON */
1226
1227#ifdef HAVE_OPAQUE_LSA
1228 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001229 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001230 {
1231 /*
1232 * This node is not configured to handle O-bit, for now.
1233 * Clear it to ignore unsupported capability proposed by neighbor.
1234 */
1235 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1236 }
1237#endif /* HAVE_OPAQUE_LSA */
1238
Paul Jakma57c5c652010-01-07 06:12:53 +00001239 /* Add event to thread. */
1240 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1241
paul718e3742002-12-13 20:15:29 +00001242 /* Process DD packet by neighbor status. */
1243 switch (nbr->state)
1244 {
1245 case NSM_Down:
1246 case NSM_Attempt:
1247 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001248 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001249 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001250 LOOKUP (ospf_nsm_state_msg, nbr->state));
1251 break;
1252 case NSM_Init:
1253 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1254 /* If the new state is ExStart, the processing of the current
1255 packet should then continue in this new state by falling
1256 through to case ExStart below. */
1257 if (nbr->state != NSM_ExStart)
1258 break;
1259 case NSM_ExStart:
1260 /* Initial DBD */
1261 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1262 (size == OSPF_DB_DESC_MIN_SIZE))
1263 {
paul68980082003-03-25 05:07:42 +00001264 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001265 {
1266 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001267 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001268 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001269 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001270
1271 /* Reset I/MS */
1272 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001273 }
1274 else
1275 {
1276 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001277 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001278 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001279 break;
1280 }
1281 }
1282 /* Ack from the Slave */
1283 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1284 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001285 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001286 {
ajs17eaa722004-12-29 21:04:48 +00001287 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001288 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001289 /* Reset I, leaving MS */
1290 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001291 }
1292 else
1293 {
ajs3aa8d5f2004-12-11 18:00:06 +00001294 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1295 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001296 break;
1297 }
1298
1299 /* This is where the real Options are saved */
1300 nbr->options = dd->options;
1301
1302#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001303 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001304 {
1305 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001306 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001307 inet_ntoa (nbr->router_id),
1308 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1309
1310 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1311 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1312 {
paul6d452762005-11-03 11:15:44 +00001313 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1314 "Opaque-LSAs cannot be reliably advertised "
1315 "in this network.",
1316 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001317 /* This situation is undesirable, but not a real error. */
1318 }
1319 }
1320#endif /* HAVE_OPAQUE_LSA */
1321
1322 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1323
1324 /* continue processing rest of packet. */
1325 ospf_db_desc_proc (s, oi, nbr, dd, size);
1326 break;
1327 case NSM_Exchange:
1328 if (ospf_db_desc_is_dup (dd, nbr))
1329 {
1330 if (IS_SET_DD_MS (nbr->dd_flags))
1331 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001332 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001333 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001334 else
1335 /* Slave: cause to retransmit the last Database Description. */
1336 {
paul6d452762005-11-03 11:15:44 +00001337 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001338 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001339 ospf_db_desc_resend (nbr);
1340 }
1341 break;
1342 }
1343
1344 /* Otherwise DD packet should be checked. */
1345 /* Check Master/Slave bit mismatch */
1346 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1347 {
ajs3aa8d5f2004-12-11 18:00:06 +00001348 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1349 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001350 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1351 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001352 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001353 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001354 break;
1355 }
1356
1357 /* Check initialize bit is set. */
1358 if (IS_SET_DD_I (dd->flags))
1359 {
paul6d452762005-11-03 11:15:44 +00001360 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001361 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001362 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1363 break;
1364 }
1365
1366 /* Check DD Options. */
1367 if (dd->options != nbr->options)
1368 {
1369#ifdef ORIGINAL_CODING
1370 /* Save the new options for debugging */
1371 nbr->options = dd->options;
1372#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001373 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1374 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001375 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1376 break;
1377 }
1378
1379 /* Check DD sequence number. */
1380 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1381 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1382 (!IS_SET_DD_MS (nbr->dd_flags) &&
1383 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1384 {
ajs3aa8d5f2004-12-11 18:00:06 +00001385 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1386 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001387 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1388 break;
1389 }
1390
1391 /* Continue processing rest of packet. */
1392 ospf_db_desc_proc (s, oi, nbr, dd, size);
1393 break;
1394 case NSM_Loading:
1395 case NSM_Full:
1396 if (ospf_db_desc_is_dup (dd, nbr))
1397 {
1398 if (IS_SET_DD_MS (nbr->dd_flags))
1399 {
1400 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001401 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1402 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001403 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001404 break;
1405 }
1406 else
1407 {
1408 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001409 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001410 t = tv_sub (now, nbr->last_send_ts);
1411 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1412 {
1413 /* In states Loading and Full the slave must resend
1414 its last Database Description packet in response to
1415 duplicate Database Description packets received
1416 from the master. For this reason the slave must
1417 wait RouterDeadInterval seconds before freeing the
1418 last Database Description packet. Reception of a
1419 Database Description packet from the master after
1420 this interval will generate a SeqNumberMismatch
1421 neighbor event. RFC2328 Section 10.8 */
1422 ospf_db_desc_resend (nbr);
1423 break;
1424 }
1425 }
1426 }
1427
1428 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1429 break;
1430 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001431 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1432 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001433 break;
1434 }
1435}
1436
1437#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1438
1439/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001440static void
paul718e3742002-12-13 20:15:29 +00001441ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1442 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1443{
1444 struct ospf_neighbor *nbr;
1445 u_int32_t ls_type;
1446 struct in_addr ls_id;
1447 struct in_addr adv_router;
1448 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001449 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001450 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001451
1452 /* Increment statistics. */
1453 oi->ls_req_in++;
1454
pauld3f0d622004-05-05 15:27:15 +00001455 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001456 if (nbr == NULL)
1457 {
1458 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1459 inet_ntoa (ospfh->router_id));
1460 return;
1461 }
1462
Paul Jakma57c5c652010-01-07 06:12:53 +00001463 /* Add event to thread. */
1464 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1465
paul718e3742002-12-13 20:15:29 +00001466 /* Neighbor State should be Exchange or later. */
1467 if (nbr->state != NSM_Exchange &&
1468 nbr->state != NSM_Loading &&
1469 nbr->state != NSM_Full)
1470 {
ajsbec595a2004-11-30 22:38:43 +00001471 zlog_warn ("Link State Request received from %s: "
1472 "Neighbor state is %s, packet discarded.",
1473 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001474 LOOKUP (ospf_nsm_state_msg, nbr->state));
1475 return;
1476 }
1477
1478 /* Send Link State Update for ALL requested LSAs. */
1479 ls_upd = list_new ();
1480 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1481
1482 while (size >= OSPF_LSA_KEY_SIZE)
1483 {
1484 /* Get one slice of Link State Request. */
1485 ls_type = stream_getl (s);
1486 ls_id.s_addr = stream_get_ipv4 (s);
1487 adv_router.s_addr = stream_get_ipv4 (s);
1488
1489 /* Verify LSA type. */
1490 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1491 {
1492 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1493 list_delete (ls_upd);
1494 return;
1495 }
1496
1497 /* Search proper LSA in LSDB. */
1498 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1499 if (find == NULL)
1500 {
1501 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1502 list_delete (ls_upd);
1503 return;
1504 }
1505
gdt86f1fd92005-01-10 14:20:43 +00001506 /* Packet overflows MTU size, send immediately. */
1507 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001508 {
1509 if (oi->type == OSPF_IFTYPE_NBMA)
1510 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1511 else
1512 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1513
1514 /* Only remove list contents. Keep ls_upd. */
1515 list_delete_all_node (ls_upd);
1516
1517 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1518 }
1519
1520 /* Append LSA to update list. */
1521 listnode_add (ls_upd, find);
1522 length += ntohs (find->data->length);
1523
1524 size -= OSPF_LSA_KEY_SIZE;
1525 }
1526
1527 /* Send rest of Link State Update. */
1528 if (listcount (ls_upd) > 0)
1529 {
1530 if (oi->type == OSPF_IFTYPE_NBMA)
1531 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1532 else
1533 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1534
1535 list_delete (ls_upd);
1536 }
1537 else
1538 list_free (ls_upd);
1539}
1540
1541/* Get the list of LSAs from Link State Update packet.
1542 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001543static struct list *
paul718e3742002-12-13 20:15:29 +00001544ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1545 struct ospf_interface *oi, size_t size)
1546{
1547 u_int16_t count, sum;
1548 u_int32_t length;
1549 struct lsa_header *lsah;
1550 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001551 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001552
1553 lsas = list_new ();
1554
1555 count = stream_getl (s);
1556 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1557
1558 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001559 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001560 {
1561 lsah = (struct lsa_header *) STREAM_PNT (s);
1562 length = ntohs (lsah->length);
1563
1564 if (length > size)
1565 {
1566 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1567 break;
1568 }
1569
1570 /* Validate the LSA's LS checksum. */
1571 sum = lsah->checksum;
1572 if (sum != ospf_lsa_checksum (lsah))
1573 {
Jaroslav Fojtik223da1a2011-12-11 18:22:16 +04001574 /* (bug #685) more details in a one-line message make it possible
1575 * to identify problem source on the one hand and to have a better
1576 * chance to compress repeated messages in syslog on the other */
1577 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1578 sum, lsah->checksum, inet_ntoa (lsah->id),
1579 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1580 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001581 continue;
1582 }
1583
1584 /* Examine the LSA's LS type. */
1585 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1586 {
1587 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1588 continue;
1589 }
1590
1591 /*
1592 * What if the received LSA's age is greater than MaxAge?
1593 * Treat it as a MaxAge case -- endo.
1594 */
1595 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1596 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1597
1598#ifdef HAVE_OPAQUE_LSA
1599 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1600 {
1601#ifdef STRICT_OBIT_USAGE_CHECK
1602 if ((IS_OPAQUE_LSA(lsah->type) &&
1603 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1604 || (! IS_OPAQUE_LSA(lsah->type) &&
1605 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1606 {
1607 /*
1608 * This neighbor must know the exact usage of O-bit;
1609 * the bit will be set in Type-9,10,11 LSAs only.
1610 */
1611 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1612 continue;
1613 }
1614#endif /* STRICT_OBIT_USAGE_CHECK */
1615
1616 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1617 if (lsah->type == OSPF_OPAQUE_AS_LSA
1618 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1619 {
1620 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001621 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 +00001622 continue;
1623 }
1624 }
1625 else if (IS_OPAQUE_LSA(lsah->type))
1626 {
1627 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1628 continue;
1629 }
1630#endif /* HAVE_OPAQUE_LSA */
1631
1632 /* Create OSPF LSA instance. */
1633 lsa = ospf_lsa_new ();
1634
1635 /* We may wish to put some error checking if type NSSA comes in
1636 and area not in NSSA mode */
1637 switch (lsah->type)
1638 {
1639 case OSPF_AS_EXTERNAL_LSA:
1640#ifdef HAVE_OPAQUE_LSA
1641 case OSPF_OPAQUE_AS_LSA:
1642 lsa->area = NULL;
1643 break;
1644 case OSPF_OPAQUE_LINK_LSA:
1645 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1646 /* Fallthrough */
1647#endif /* HAVE_OPAQUE_LSA */
1648 default:
1649 lsa->area = oi->area;
1650 break;
1651 }
1652
1653 lsa->data = ospf_lsa_data_new (length);
1654 memcpy (lsa->data, lsah, length);
1655
1656 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001657 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001658 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1659 listnode_add (lsas, lsa);
1660 }
1661
1662 return lsas;
1663}
1664
1665/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001666static void
hasso52dc7ee2004-09-23 19:18:23 +00001667ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001668{
paul1eb8ef22005-04-07 07:30:20 +00001669 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001670 struct ospf_lsa *lsa;
1671
paul1eb8ef22005-04-07 07:30:20 +00001672 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1673 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001674
1675 list_delete (lsas);
1676}
1677
1678/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001679static void
paul718e3742002-12-13 20:15:29 +00001680ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1681 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1682{
1683 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001684 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001685 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001686 struct ospf_lsa *lsa = NULL;
1687 /* unsigned long ls_req_found = 0; */
1688
1689 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1690
1691 /* Increment statistics. */
1692 oi->ls_upd_in++;
1693
1694 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001695 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001696 if (nbr == NULL)
1697 {
1698 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1699 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1700 return;
1701 }
1702
Paul Jakma57c5c652010-01-07 06:12:53 +00001703 /* Add event to thread. */
1704 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1705
paul718e3742002-12-13 20:15:29 +00001706 /* Check neighbor state. */
1707 if (nbr->state < NSM_Exchange)
1708 {
ajs3aa8d5f2004-12-11 18:00:06 +00001709 zlog_warn ("Link State Update: "
1710 "Neighbor[%s] state %s is less than Exchange",
1711 inet_ntoa (ospfh->router_id),
1712 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001713 return;
1714 }
1715
1716 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1717 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1718 * of section 13.
1719 */
1720 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1721
1722#ifdef HAVE_OPAQUE_LSA
1723 /*
paul718e3742002-12-13 20:15:29 +00001724 * If self-originated Opaque-LSAs that have flooded before restart
1725 * are contained in the received LSUpd message, corresponding LSReq
1726 * messages to be sent may have to be modified.
1727 * To eliminate possible race conditions such that flushing and normal
1728 * updating for the same LSA would take place alternately, this trick
1729 * must be done before entering to the loop below.
1730 */
paul69310a62005-05-11 18:09:59 +00001731 /* XXX: Why is this Opaque specific? Either our core code is deficient
1732 * and this should be fixed generally, or Opaque is inventing strawman
1733 * problems */
paul718e3742002-12-13 20:15:29 +00001734 ospf_opaque_adjust_lsreq (nbr, lsas);
1735#endif /* HAVE_OPAQUE_LSA */
1736
1737#define DISCARD_LSA(L,N) {\
1738 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001739 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 +00001740 ospf_lsa_discard (L); \
1741 continue; }
1742
1743 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001744 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001745 {
1746 struct ospf_lsa *ls_ret, *current;
1747 int ret = 1;
1748
paul718e3742002-12-13 20:15:29 +00001749 if (IS_DEBUG_OSPF_NSSA)
1750 {
1751 char buf1[INET_ADDRSTRLEN];
1752 char buf2[INET_ADDRSTRLEN];
1753 char buf3[INET_ADDRSTRLEN];
1754
ajs2a42e282004-12-08 18:43:03 +00001755 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001756 lsa->data->type,
1757 inet_ntop (AF_INET, &ospfh->router_id,
1758 buf1, INET_ADDRSTRLEN),
1759 inet_ntop (AF_INET, &lsa->data->id,
1760 buf2, INET_ADDRSTRLEN),
1761 inet_ntop (AF_INET, &lsa->data->adv_router,
1762 buf3, INET_ADDRSTRLEN));
1763 }
paul718e3742002-12-13 20:15:29 +00001764
1765 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1766
1767 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1768
1769 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1770
1771 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1772
1773 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1774
1775 /* Do take in Type-7's if we are an NSSA */
1776
1777 /* If we are also an ABR, later translate them to a Type-5 packet */
1778
1779 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1780 translate them to a separate Type-5 packet. */
1781
1782 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1783 /* Reject from STUB or NSSA */
1784 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1785 {
paul718e3742002-12-13 20:15:29 +00001786 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001787 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001788 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001789 }
1790
paul718e3742002-12-13 20:15:29 +00001791 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1792 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1793 {
paul718e3742002-12-13 20:15:29 +00001794 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001795 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001796 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001797 }
paul718e3742002-12-13 20:15:29 +00001798
1799 /* Find the LSA in the current database. */
1800
1801 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1802
1803 /* If the LSA's LS age is equal to MaxAge, and there is currently
1804 no instance of the LSA in the router's link state database,
1805 and none of router's neighbors are in states Exchange or Loading,
1806 then take the following actions. */
1807
1808 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001809 (ospf_nbr_count (oi, NSM_Exchange) +
1810 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001811 {
1812 /* Response Link State Acknowledgment. */
1813 ospf_ls_ack_send (nbr, lsa);
1814
1815 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001816 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1817 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001818 DISCARD_LSA (lsa, 3);
1819 }
1820
1821#ifdef HAVE_OPAQUE_LSA
1822 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001823 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001824 {
1825 /*
1826 * Even if initial flushing seems to be completed, there might
1827 * be a case that self-originated LSA with MaxAge still remain
1828 * in the routing domain.
1829 * Just send an LSAck message to cease retransmission.
1830 */
1831 if (IS_LSA_MAXAGE (lsa))
1832 {
1833 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1834 ospf_ls_ack_send (nbr, lsa);
1835 ospf_lsa_discard (lsa);
1836
1837 if (current != NULL && ! IS_LSA_MAXAGE (current))
1838 ospf_opaque_lsa_refresh_schedule (current);
1839 continue;
1840 }
1841
1842 /*
1843 * If an instance of self-originated Opaque-LSA is not found
1844 * in the LSDB, there are some possible cases here.
1845 *
1846 * 1) This node lost opaque-capability after restart.
1847 * 2) Else, a part of opaque-type is no more supported.
1848 * 3) Else, a part of opaque-id is no more supported.
1849 *
1850 * Anyway, it is still this node's responsibility to flush it.
1851 * Otherwise, the LSA instance remains in the routing domain
1852 * until its age reaches to MaxAge.
1853 */
paul69310a62005-05-11 18:09:59 +00001854 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001855 if (current == NULL)
1856 {
1857 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001858 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1859 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001860
1861 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001862
1863 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1864 ospf_ls_ack_send (nbr, lsa);
1865
paul718e3742002-12-13 20:15:29 +00001866 continue;
1867 }
1868 }
1869#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001870
hassocb05eb22004-02-11 21:10:19 +00001871 /* It might be happen that received LSA is self-originated network LSA, but
1872 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1873 * Link State ID is one of the router's own IP interface addresses but whose
1874 * Advertising Router is not equal to the router's own Router ID
1875 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1876 */
1877
1878 if(lsa->data->type == OSPF_NETWORK_LSA)
1879 {
paul1eb8ef22005-04-07 07:30:20 +00001880 struct listnode *oinode, *oinnode;
1881 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001882 int Flag = 0;
1883
paul1eb8ef22005-04-07 07:30:20 +00001884 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001885 {
hassocb05eb22004-02-11 21:10:19 +00001886 if(out_if == NULL)
1887 break;
1888
1889 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1890 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1891 {
1892 if(out_if->network_lsa_self)
1893 {
1894 ospf_lsa_flush_area(lsa,out_if->area);
1895 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001896 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001897 lsa, (int) lsa->data->type);
1898 ospf_lsa_discard (lsa);
1899 Flag = 1;
1900 }
1901 break;
1902 }
1903 }
1904 if(Flag)
1905 continue;
1906 }
paul718e3742002-12-13 20:15:29 +00001907
1908 /* (5) Find the instance of this LSA that is currently contained
1909 in the router's link state database. If there is no
1910 database copy, or the received LSA is more recent than
1911 the database copy the following steps must be performed. */
1912
1913 if (current == NULL ||
1914 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1915 {
1916 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001917 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001918 DISCARD_LSA (lsa, 4);
1919 continue;
1920 }
1921
1922 /* (6) Else, If there is an instance of the LSA on the sending
1923 neighbor's Link state request list, an error has occurred in
1924 the Database Exchange process. In this case, restart the
1925 Database Exchange process by generating the neighbor event
1926 BadLSReq for the sending neighbor and stop processing the
1927 Link State Update packet. */
1928
1929 if (ospf_ls_request_lookup (nbr, lsa))
1930 {
1931 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001932 zlog_warn("LSA[%s] instance exists on Link state request list",
1933 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001934
1935 /* Clean list of LSAs. */
1936 ospf_upd_list_clean (lsas);
1937 /* this lsa is not on lsas list already. */
1938 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001939 return;
1940 }
1941
1942 /* If the received LSA is the same instance as the database copy
1943 (i.e., neither one is more recent) the following two steps
1944 should be performed: */
1945
1946 if (ret == 0)
1947 {
1948 /* If the LSA is listed in the Link state retransmission list
1949 for the receiving adjacency, the router itself is expecting
1950 an acknowledgment for this LSA. The router should treat the
1951 received LSA as an acknowledgment by removing the LSA from
1952 the Link state retransmission list. This is termed an
1953 "implied acknowledgment". */
1954
1955 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1956
1957 if (ls_ret != NULL)
1958 {
1959 ospf_ls_retransmit_delete (nbr, ls_ret);
1960
1961 /* Delayed acknowledgment sent if advertisement received
1962 from Designated Router, otherwise do nothing. */
1963 if (oi->state == ISM_Backup)
1964 if (NBR_IS_DR (nbr))
1965 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1966
1967 DISCARD_LSA (lsa, 5);
1968 }
1969 else
1970 /* Acknowledge the receipt of the LSA by sending a
1971 Link State Acknowledgment packet back out the receiving
1972 interface. */
1973 {
1974 ospf_ls_ack_send (nbr, lsa);
1975 DISCARD_LSA (lsa, 6);
1976 }
1977 }
1978
1979 /* The database copy is more recent. If the database copy
1980 has LS age equal to MaxAge and LS sequence number equal to
1981 MaxSequenceNumber, simply discard the received LSA without
1982 acknowledging it. (In this case, the LSA's LS sequence number is
1983 wrapping, and the MaxSequenceNumber LSA must be completely
1984 flushed before any new LSA instance can be introduced). */
1985
1986 else if (ret > 0) /* Database copy is more recent */
1987 {
1988 if (IS_LSA_MAXAGE (current) &&
1989 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1990 {
1991 DISCARD_LSA (lsa, 7);
1992 }
1993 /* Otherwise, as long as the database copy has not been sent in a
1994 Link State Update within the last MinLSArrival seconds, send the
1995 database copy back to the sending neighbor, encapsulated within
1996 a Link State Update Packet. The Link State Update Packet should
1997 be sent directly to the neighbor. In so doing, do not put the
1998 database copy of the LSA on the neighbor's link state
1999 retransmission list, and do not acknowledge the received (less
2000 recent) LSA instance. */
2001 else
2002 {
2003 struct timeval now;
2004
Paul Jakma2518efd2006-08-27 06:49:29 +00002005 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00002006
2007 if (tv_cmp (tv_sub (now, current->tv_orig),
Paul Jakma2c9f8e32010-01-11 16:22:12 +00002008 int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
paul718e3742002-12-13 20:15:29 +00002009 /* Trap NSSA type later.*/
2010 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2011 DISCARD_LSA (lsa, 8);
2012 }
2013 }
2014 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03002015#undef DISCARD_LSA
2016
paul718e3742002-12-13 20:15:29 +00002017 assert (listcount (lsas) == 0);
2018 list_delete (lsas);
2019}
2020
2021/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00002022static void
paul718e3742002-12-13 20:15:29 +00002023ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2024 struct stream *s, struct ospf_interface *oi, u_int16_t size)
2025{
2026 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00002027
paul718e3742002-12-13 20:15:29 +00002028 /* increment statistics. */
2029 oi->ls_ack_in++;
2030
pauld3f0d622004-05-05 15:27:15 +00002031 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00002032 if (nbr == NULL)
2033 {
2034 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2035 inet_ntoa (ospfh->router_id));
2036 return;
2037 }
2038
Paul Jakma57c5c652010-01-07 06:12:53 +00002039 /* Add event to thread. */
2040 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2041
paul718e3742002-12-13 20:15:29 +00002042 if (nbr->state < NSM_Exchange)
2043 {
ajs3aa8d5f2004-12-11 18:00:06 +00002044 zlog_warn ("Link State Acknowledgment: "
2045 "Neighbor[%s] state %s is less than Exchange",
2046 inet_ntoa (ospfh->router_id),
2047 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00002048 return;
2049 }
paul69310a62005-05-11 18:09:59 +00002050
paul718e3742002-12-13 20:15:29 +00002051 while (size >= OSPF_LSA_HEADER_SIZE)
2052 {
2053 struct ospf_lsa *lsa, *lsr;
2054
2055 lsa = ospf_lsa_new ();
2056 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2057
2058 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2059 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002060 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002061
2062 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2063 {
2064 lsa->data = NULL;
2065 ospf_lsa_discard (lsa);
2066 continue;
2067 }
2068
2069 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2070
2071 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2072 {
2073#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002074 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002075 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002076#endif /* HAVE_OPAQUE_LSA */
2077
2078 ospf_ls_retransmit_delete (nbr, lsr);
2079 }
2080
2081 lsa->data = NULL;
2082 ospf_lsa_discard (lsa);
2083 }
2084
paul718e3742002-12-13 20:15:29 +00002085 return;
paul718e3742002-12-13 20:15:29 +00002086}
2087
ajs038163f2005-02-17 19:55:59 +00002088static struct stream *
ajs5c333492005-02-23 15:43:01 +00002089ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002090{
2091 int ret;
ajs5c333492005-02-23 15:43:01 +00002092 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002093 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002094 unsigned int ifindex = 0;
2095 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002096 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002097 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002098 struct msghdr msgh;
2099
paul68defd62004-09-27 07:27:13 +00002100 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002101 msgh.msg_iov = &iov;
2102 msgh.msg_iovlen = 1;
2103 msgh.msg_control = (caddr_t) buff;
2104 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002105
ajs5c333492005-02-23 15:43:01 +00002106 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2107 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002108 {
ajs5c333492005-02-23 15:43:01 +00002109 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2110 return NULL;
2111 }
paul69310a62005-05-11 18:09:59 +00002112 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002113 {
2114 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2115 "(ip header size is %u)",
2116 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002117 return NULL;
2118 }
paul18b12c32004-10-05 14:38:29 +00002119
ajs5c333492005-02-23 15:43:01 +00002120 /* Note that there should not be alignment problems with this assignment
2121 because this is at the beginning of the stream data buffer. */
2122 iph = (struct ip *) STREAM_DATA(ibuf);
2123 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002124
ajs5c333492005-02-23 15:43:01 +00002125 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002126
Dmitrij Tejblumde5ccb92011-12-12 20:30:10 +04002127#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
paul718e3742002-12-13 20:15:29 +00002128 /*
2129 * Kernel network code touches incoming IP header parameters,
2130 * before protocol specific processing.
2131 *
2132 * 1) Convert byteorder to host representation.
2133 * --> ip_len, ip_id, ip_off
2134 *
2135 * 2) Adjust ip_len to strip IP header size!
2136 * --> If user process receives entire IP packet via RAW
2137 * socket, it must consider adding IP header size to
2138 * the "ip_len" field of "ip" structure.
2139 *
2140 * For more details, see <netinet/ip_input.c>.
2141 */
ajs5c333492005-02-23 15:43:01 +00002142 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002143#endif
2144
David BÉRARD0150c9c2010-05-11 10:17:53 +02002145#if defined(__DragonFly__)
2146 /*
2147 * in DragonFly's raw socket, ip_len/ip_off are read
2148 * in network byte order.
2149 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2150 */
2151 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2152#endif
2153
paul863082d2004-08-19 04:43:43 +00002154 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002155
2156 *ifp = if_lookup_by_index (ifindex);
2157
2158 if (ret != ip_len)
2159 {
ajs5c333492005-02-23 15:43:01 +00002160 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2161 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002162 return NULL;
2163 }
2164
2165 return ibuf;
2166}
2167
paul4dadc292005-05-06 21:37:42 +00002168static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002169ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002170 struct ip *iph, struct ospf_header *ospfh)
2171{
2172 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002173 struct ospf_vl_data *vl_data;
2174 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002175 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002176
2177 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2178 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002179 return NULL;
paul718e3742002-12-13 20:15:29 +00002180
pauld3f0d622004-05-05 15:27:15 +00002181 /* look for local OSPF interface matching the destination
2182 * to determine Area ID. We presume therefore the destination address
2183 * is unique, or at least (for "unnumbered" links), not used in other
2184 * areas
2185 */
2186 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2187 iph->ip_dst)) == NULL)
2188 return NULL;
paul718e3742002-12-13 20:15:29 +00002189
paul1eb8ef22005-04-07 07:30:20 +00002190 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002191 {
paul020709f2003-04-04 02:44:16 +00002192 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002193 if (!vl_area)
2194 continue;
2195
2196 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2197 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2198 {
2199 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002200 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002201 IF_NAME (vl_data->vl_oi));
2202 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2203 {
2204 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002205 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002206 return NULL;
2207 }
2208
2209 return vl_data->vl_oi;
2210 }
2211 }
2212
2213 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002214 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002215
pauld3f0d622004-05-05 15:27:15 +00002216 return NULL;
paul718e3742002-12-13 20:15:29 +00002217}
2218
Paul Jakmaf63f06d2011-04-08 12:44:43 +01002219static int
paul718e3742002-12-13 20:15:29 +00002220ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2221{
2222 /* Check match the Area ID of the receiving interface. */
2223 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2224 return 1;
2225
2226 return 0;
2227}
2228
2229/* Unbound socket will accept any Raw IP packets if proto is matched.
2230 To prevent it, compare src IP address and i/f address with masking
2231 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002232static int
paul718e3742002-12-13 20:15:29 +00002233ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2234{
2235 struct in_addr mask, me, him;
2236
2237 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2238 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2239 return 1;
2240
2241 masklen2ip (oi->address->prefixlen, &mask);
2242
2243 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2244 him.s_addr = ip_src.s_addr & mask.s_addr;
2245
2246 if (IPV4_ADDR_SAME (&me, &him))
2247 return 1;
2248
2249 return 0;
2250}
2251
paul4dadc292005-05-06 21:37:42 +00002252static int
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002253ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
paul718e3742002-12-13 20:15:29 +00002254{
2255 int ret = 0;
2256 struct crypt_key *ck;
2257
2258 switch (ntohs (ospfh->auth_type))
2259 {
2260 case OSPF_AUTH_NULL:
2261 ret = 1;
2262 break;
2263 case OSPF_AUTH_SIMPLE:
2264 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2265 ret = 1;
2266 else
2267 ret = 0;
2268 break;
2269 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002270 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002271 {
2272 ret = 0;
2273 break;
2274 }
2275
2276 /* This is very basic, the digest processing is elsewhere */
2277 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2278 ospfh->u.crypt.key_id == ck->key_id &&
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002279 ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE)
paul718e3742002-12-13 20:15:29 +00002280 ret = 1;
2281 else
2282 ret = 0;
2283 break;
2284 default:
2285 ret = 0;
2286 break;
2287 }
2288
2289 return ret;
2290}
2291
paul4dadc292005-05-06 21:37:42 +00002292static int
paul718e3742002-12-13 20:15:29 +00002293ospf_check_sum (struct ospf_header *ospfh)
2294{
2295 u_int32_t ret;
2296 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002297
2298 /* clear auth_data for checksum. */
2299 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2300
2301 /* keep checksum and clear. */
2302 sum = ospfh->checksum;
2303 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2304
2305 /* calculate checksum. */
2306 ret = in_cksum (ospfh, ntohs (ospfh->length));
2307
2308 if (ret != sum)
2309 {
2310 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2311 ret, sum);
2312 return 0;
2313 }
2314
2315 return 1;
2316}
2317
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002318/* Verify a complete OSPF packet for proper sizing/alignment. */
2319static unsigned
2320ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2321{
2322 u_int16_t bytesdeclared;
2323
2324 /* Length, 1st approximation. */
2325 if (bytesonwire < OSPF_HEADER_SIZE)
2326 {
2327 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2328 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2329 return MSG_NG;
2330 }
2331 /* Now it is safe to access header fields. Performing length check, allow
2332 * for possible extra bytes of crypto auth/padding, which are not counted
2333 * in the OSPF header "length" field. */
2334 bytesdeclared = ntohs (oh->length);
2335 if (bytesdeclared > bytesonwire)
2336 {
2337 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2338 zlog_debug ("%s: packet length error (%u real, %u declared)",
2339 __func__, bytesonwire, bytesdeclared);
2340 return MSG_NG;
2341 }
2342 /* Length, 2nd approximation. The type-specific constraint is checked
2343 against declared length, not amount of bytes on wire. */
2344 if
2345 (
2346 oh->type >= OSPF_MSG_HELLO &&
2347 oh->type <= OSPF_MSG_LS_ACK &&
2348 bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2349 )
2350 {
2351 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2352 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2353 bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2354 return MSG_NG;
2355 }
2356 return MSG_OK;
2357}
2358
paul718e3742002-12-13 20:15:29 +00002359/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002360static int
paul718e3742002-12-13 20:15:29 +00002361ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2362 struct ip *iph, struct ospf_header *ospfh)
2363{
2364 /* check version. */
2365 if (ospfh->version != OSPF_VERSION)
2366 {
2367 zlog_warn ("interface %s: ospf_read version number mismatch.",
2368 IF_NAME (oi));
2369 return -1;
2370 }
2371
Denis Ovsienko71775042011-09-26 13:18:02 +04002372 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2373 if (ospfh->type < 1 || ospfh->type > 5)
2374 {
2375 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2376 return -1;
2377 }
2378
paul718e3742002-12-13 20:15:29 +00002379 /* Check Area ID. */
2380 if (!ospf_check_area_id (oi, ospfh))
2381 {
2382 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2383 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2384 return -1;
2385 }
2386
2387 /* Check network mask, Silently discarded. */
2388 if (! ospf_check_network_mask (oi, iph->ip_src))
2389 {
2390 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2391 IF_NAME (oi), inet_ntoa (iph->ip_src));
2392 return -1;
2393 }
2394
2395 /* Check authentication. */
2396 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2397 {
paulc6371712006-01-17 17:49:53 +00002398 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2399 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002400 return -1;
2401 }
2402
Denis Ovsienkoe5259142012-01-30 16:07:18 +04002403 if (! ospf_check_auth (oi, ospfh))
paul718e3742002-12-13 20:15:29 +00002404 {
2405 zlog_warn ("interface %s: ospf_read authentication failed.",
2406 IF_NAME (oi));
2407 return -1;
2408 }
2409
2410 /* if check sum is invalid, packet is discarded. */
2411 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2412 {
2413 if (! ospf_check_sum (ospfh))
2414 {
2415 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2416 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2417 return -1;
2418 }
2419 }
2420 else
2421 {
2422 if (ospfh->checksum != 0)
2423 return -1;
Denis Ovsienko2d8223c2012-01-30 20:32:39 +04002424 if (ospf_check_md5_digest (oi, ospfh) == 0)
paul718e3742002-12-13 20:15:29 +00002425 {
2426 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2427 IF_NAME (oi));
2428 return -1;
2429 }
2430 }
2431
2432 return 0;
2433}
2434
2435/* Starting point of packet process function. */
2436int
2437ospf_read (struct thread *thread)
2438{
2439 int ret;
2440 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002441 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002442 struct ospf_interface *oi;
2443 struct ip *iph;
2444 struct ospf_header *ospfh;
2445 u_int16_t length;
2446 struct interface *ifp;
2447
2448 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002449 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002450
2451 /* prepare for next packet. */
2452 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002453
ajs5c333492005-02-23 15:43:01 +00002454 stream_reset(ospf->ibuf);
2455 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002456 return -1;
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002457 /* This raw packet is known to be at least as big as its IP header. */
paul718e3742002-12-13 20:15:29 +00002458
ajs5c333492005-02-23 15:43:01 +00002459 /* Note that there should not be alignment problems with this assignment
2460 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002461 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002462 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002463
paulac191232004-10-22 12:05:17 +00002464 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002465 /* Handle cases where the platform does not support retrieving the ifindex,
2466 and also platforms (such as Solaris 8) that claim to support ifindex
2467 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002468 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002469
pauld3f0d622004-05-05 15:27:15 +00002470 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002471 return 0;
paul718e3742002-12-13 20:15:29 +00002472
2473 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002474 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002475 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002476
paul718e3742002-12-13 20:15:29 +00002477 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002478 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002479 {
pauld3241812003-09-29 12:42:39 +00002480 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2481 {
ajs2a42e282004-12-08 18:43:03 +00002482 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002483 inet_ntoa (iph->ip_src));
2484 }
paul718e3742002-12-13 20:15:29 +00002485 return 0;
2486 }
2487
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002488 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2489 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002490 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko61ab0302011-09-26 13:17:52 +04002491
paul718e3742002-12-13 20:15:29 +00002492 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
Denis Ovsienko75c8eab2012-01-30 15:41:39 +04002493 if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
2494 return -1;
2495 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002496
2497 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002498 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002499
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002500 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2501 after the passive/backbone/other checks below are passed. These checks
2502 in turn access the fields of unverified "ospfh" structure for their own
2503 purposes and must remain very accurate in doing this. */
Denis Ovsienko71775042011-09-26 13:18:02 +04002504
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002505 /* If incoming interface is passive one, ignore it. */
2506 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2507 {
2508 char buf[3][INET_ADDRSTRLEN];
2509
2510 if (IS_DEBUG_OSPF_EVENT)
2511 zlog_debug ("ignoring packet from router %s sent to %s, "
2512 "received on a passive interface, %s",
2513 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2514 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2515 inet_ntop(AF_INET, &oi->address->u.prefix4,
2516 buf[2], sizeof(buf[2])));
2517
2518 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2519 {
2520 /* Try to fix multicast membership.
2521 * Some OS:es may have problems in this area,
2522 * make sure it is removed.
2523 */
2524 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2525 ospf_if_set_multicast(oi);
2526 }
2527 return 0;
2528 }
2529
2530
pauld3f0d622004-05-05 15:27:15 +00002531 /* if no local ospf_interface,
2532 * or header area is backbone but ospf_interface is not
2533 * check for VLINK interface
2534 */
2535 if ( (oi == NULL) ||
2536 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2537 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2538 )
2539 {
2540 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2541 {
Paul Jakma88871b12006-06-15 11:41:19 +00002542 if (IS_DEBUG_OSPF_EVENT)
2543 zlog_debug ("Packet from [%s] received on link %s"
2544 " but no ospf_interface",
2545 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002546 return 0;
2547 }
2548 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002549
pauld3f0d622004-05-05 15:27:15 +00002550 /* else it must be a local ospf interface, check it was received on
2551 * correct link
2552 */
2553 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002554 {
Paul Jakma11637432009-08-11 12:25:42 +01002555 if (IS_DEBUG_OSPF_EVENT)
2556 zlog_warn ("Packet from [%s] received on wrong link %s",
2557 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002558 return 0;
2559 }
ajs847947f2005-02-02 18:38:48 +00002560 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002561 {
ajsba6454e2005-02-08 15:37:30 +00002562 char buf[2][INET_ADDRSTRLEN];
2563 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002564 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002565 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2566 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2567 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002568 /* Fix multicast memberships? */
2569 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002570 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002571 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002572 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002573 if (oi->multicast_memberships)
2574 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002575 return 0;
2576 }
paul718e3742002-12-13 20:15:29 +00002577
2578 /*
2579 * If the received packet is destined for AllDRouters, the packet
2580 * should be accepted only if the received ospf interface state is
2581 * either DR or Backup -- endo.
2582 */
2583 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2584 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2585 {
ajsba6454e2005-02-08 15:37:30 +00002586 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002587 inet_ntoa (iph->ip_src), IF_NAME (oi),
2588 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002589 /* Try to fix multicast membership. */
2590 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2591 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002592 return 0;
2593 }
2594
YAMAMOTO Shigeru3aad46b2011-09-28 21:00:14 +04002595 /* Verify more OSPF header fields. */
2596 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2597 if (ret < 0)
2598 {
2599 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2600 zlog_debug ("ospf_read[%s]: Header check failed, "
2601 "dropping.",
2602 inet_ntoa (iph->ip_src));
2603 return ret;
2604 }
2605
paul718e3742002-12-13 20:15:29 +00002606 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002607 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2608 {
paul718e3742002-12-13 20:15:29 +00002609 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002610 {
ajs2a42e282004-12-08 18:43:03 +00002611 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002612 ospf_packet_dump (ibuf);
2613 }
paul718e3742002-12-13 20:15:29 +00002614
ajs2a42e282004-12-08 18:43:03 +00002615 zlog_debug ("%s received from [%s] via [%s]",
Denis Ovsienko272ca1e2012-01-15 19:12:19 +04002616 LOOKUP (ospf_packet_type_str, ospfh->type),
paul1aa7b392003-04-08 08:51:58 +00002617 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002618 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2619 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002620
2621 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002622 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002623 }
paul718e3742002-12-13 20:15:29 +00002624
paul9985f832005-02-09 15:51:56 +00002625 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002626
2627 /* Adjust size to message length. */
2628 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2629
2630 /* Read rest of the packet and call each sort of packet routine. */
2631 switch (ospfh->type)
2632 {
2633 case OSPF_MSG_HELLO:
2634 ospf_hello (iph, ospfh, ibuf, oi, length);
2635 break;
2636 case OSPF_MSG_DB_DESC:
2637 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2638 break;
2639 case OSPF_MSG_LS_REQ:
2640 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2641 break;
2642 case OSPF_MSG_LS_UPD:
2643 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2644 break;
2645 case OSPF_MSG_LS_ACK:
2646 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2647 break;
2648 default:
2649 zlog (NULL, LOG_WARNING,
2650 "interface %s: OSPF packet header type %d is illegal",
2651 IF_NAME (oi), ospfh->type);
2652 break;
2653 }
2654
paul718e3742002-12-13 20:15:29 +00002655 return 0;
2656}
2657
2658/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002659static void
paul718e3742002-12-13 20:15:29 +00002660ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2661{
2662 struct ospf_header *ospfh;
2663
2664 ospfh = (struct ospf_header *) STREAM_DATA (s);
2665
2666 ospfh->version = (u_char) OSPF_VERSION;
2667 ospfh->type = (u_char) type;
2668
paul68980082003-03-25 05:07:42 +00002669 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002670
2671 ospfh->checksum = 0;
2672 ospfh->area_id = oi->area->area_id;
2673 ospfh->auth_type = htons (ospf_auth_type (oi));
2674
2675 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2676
paul9985f832005-02-09 15:51:56 +00002677 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002678}
2679
2680/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002681static int
paul718e3742002-12-13 20:15:29 +00002682ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2683{
2684 struct crypt_key *ck;
2685
2686 switch (ospf_auth_type (oi))
2687 {
2688 case OSPF_AUTH_NULL:
2689 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2690 break;
2691 case OSPF_AUTH_SIMPLE:
2692 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2693 OSPF_AUTH_SIMPLE_SIZE);
2694 break;
2695 case OSPF_AUTH_CRYPTOGRAPHIC:
2696 /* If key is not set, then set 0. */
2697 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2698 {
2699 ospfh->u.crypt.zero = 0;
2700 ospfh->u.crypt.key_id = 0;
2701 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2702 }
2703 else
2704 {
paul1eb8ef22005-04-07 07:30:20 +00002705 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002706 ospfh->u.crypt.zero = 0;
2707 ospfh->u.crypt.key_id = ck->key_id;
2708 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2709 }
2710 /* note: the seq is done in ospf_make_md5_digest() */
2711 break;
2712 default:
2713 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2714 break;
2715 }
2716
2717 return 0;
2718}
2719
2720/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002721static void
paul718e3742002-12-13 20:15:29 +00002722ospf_fill_header (struct ospf_interface *oi,
2723 struct stream *s, u_int16_t length)
2724{
2725 struct ospf_header *ospfh;
2726
2727 ospfh = (struct ospf_header *) STREAM_DATA (s);
2728
2729 /* Fill length. */
2730 ospfh->length = htons (length);
2731
2732 /* Calculate checksum. */
2733 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2734 ospfh->checksum = in_cksum (ospfh, length);
2735 else
2736 ospfh->checksum = 0;
2737
2738 /* Add Authentication Data. */
2739 ospf_make_auth (oi, ospfh);
2740}
2741
paul4dadc292005-05-06 21:37:42 +00002742static int
paul718e3742002-12-13 20:15:29 +00002743ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2744{
2745 struct ospf_neighbor *nbr;
2746 struct route_node *rn;
2747 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2748 struct in_addr mask;
2749 unsigned long p;
2750 int flag = 0;
2751
2752 /* Set netmask of interface. */
2753 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2754 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2755 masklen2ip (oi->address->prefixlen, &mask);
2756 else
2757 memset ((char *) &mask, 0, sizeof (struct in_addr));
2758 stream_put_ipv4 (s, mask.s_addr);
2759
2760 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002761 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2762 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2763 else
2764 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002765
2766 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002767 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002768 OPTIONS(oi), IF_NAME (oi));
2769
2770 /* Set Options. */
2771 stream_putc (s, OPTIONS (oi));
2772
2773 /* Set Router Priority. */
2774 stream_putc (s, PRIORITY (oi));
2775
2776 /* Set Router Dead Interval. */
2777 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2778
2779 /* Set Designated Router. */
2780 stream_put_ipv4 (s, DR (oi).s_addr);
2781
paul9985f832005-02-09 15:51:56 +00002782 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002783
2784 /* Set Backup Designated Router. */
2785 stream_put_ipv4 (s, BDR (oi).s_addr);
2786
2787 /* Add neighbor seen. */
2788 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002789 if ((nbr = rn->info))
2790 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2791 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2792 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2793 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002794 {
2795 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002796 if (nbr->d_router.s_addr != 0
2797 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2798 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2799 flag = 1;
paul718e3742002-12-13 20:15:29 +00002800
2801 stream_put_ipv4 (s, nbr->router_id.s_addr);
2802 length += 4;
2803 }
2804
2805 /* Let neighbor generate BackupSeen. */
2806 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002807 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002808
2809 return length;
2810}
2811
paul4dadc292005-05-06 21:37:42 +00002812static int
paul718e3742002-12-13 20:15:29 +00002813ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2814 struct stream *s)
2815{
2816 struct ospf_lsa *lsa;
2817 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2818 u_char options;
2819 unsigned long pp;
2820 int i;
2821 struct ospf_lsdb *lsdb;
2822
2823 /* Set Interface MTU. */
2824 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2825 stream_putw (s, 0);
2826 else
2827 stream_putw (s, oi->ifp->mtu);
2828
2829 /* Set Options. */
2830 options = OPTIONS (oi);
2831#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002832 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002833 {
2834 if (IS_SET_DD_I (nbr->dd_flags)
2835 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2836 /*
2837 * Set O-bit in the outgoing DD packet for capablity negotiation,
2838 * if one of following case is applicable.
2839 *
2840 * 1) WaitTimer expiration event triggered the neighbor state to
2841 * change to Exstart, but no (valid) DD packet has received
2842 * from the neighbor yet.
2843 *
2844 * 2) At least one DD packet with O-bit on has received from the
2845 * neighbor.
2846 */
2847 SET_FLAG (options, OSPF_OPTION_O);
2848 }
2849#endif /* HAVE_OPAQUE_LSA */
2850 stream_putc (s, options);
2851
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002852 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002853 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002854 stream_putc (s, nbr->dd_flags);
2855
2856 /* Set DD Sequence Number. */
2857 stream_putl (s, nbr->dd_seqnum);
2858
Paul Jakmab5aeb442006-08-30 18:47:37 +00002859 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002860 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002861 goto empty;
paul718e3742002-12-13 20:15:29 +00002862
2863 /* Describe LSA Header from Database Summary List. */
2864 lsdb = &nbr->db_sum;
2865
2866 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2867 {
2868 struct route_table *table = lsdb->type[i].db;
2869 struct route_node *rn;
2870
2871 for (rn = route_top (table); rn; rn = route_next (rn))
2872 if ((lsa = rn->info) != NULL)
2873 {
2874#ifdef HAVE_OPAQUE_LSA
2875 if (IS_OPAQUE_LSA (lsa->data->type)
2876 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2877 {
2878 /* Suppress advertising opaque-informations. */
2879 /* Remove LSA from DB summary list. */
2880 ospf_lsdb_delete (lsdb, lsa);
2881 continue;
2882 }
2883#endif /* HAVE_OPAQUE_LSA */
2884
2885 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2886 {
2887 struct lsa_header *lsah;
2888 u_int16_t ls_age;
2889
2890 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002891 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002892 break;
2893
2894 /* Keep pointer to LS age. */
2895 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002896 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002897
2898 /* Proceed stream pointer. */
2899 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2900 length += OSPF_LSA_HEADER_SIZE;
2901
2902 /* Set LS age. */
2903 ls_age = LS_AGE (lsa);
2904 lsah->ls_age = htons (ls_age);
2905
2906 }
2907
2908 /* Remove LSA from DB summary list. */
2909 ospf_lsdb_delete (lsdb, lsa);
2910 }
2911 }
2912
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002913 /* Update 'More' bit */
2914 if (ospf_db_summary_isempty (nbr))
2915 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002916empty:
2917 if (nbr->state >= NSM_Exchange)
2918 {
2919 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2920 /* Rewrite DD flags */
2921 stream_putc_at (s, pp, nbr->dd_flags);
2922 }
2923 else
2924 {
2925 assert (IS_SET_DD_M(nbr->dd_flags));
2926 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002927 }
paul718e3742002-12-13 20:15:29 +00002928 return length;
2929}
2930
paul4dadc292005-05-06 21:37:42 +00002931static int
paul718e3742002-12-13 20:15:29 +00002932ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2933 unsigned long delta, struct ospf_neighbor *nbr,
2934 struct ospf_lsa *lsa)
2935{
2936 struct ospf_interface *oi;
2937
2938 oi = nbr->oi;
2939
2940 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002941 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002942 return 0;
2943
2944 stream_putl (s, lsa->data->type);
2945 stream_put_ipv4 (s, lsa->data->id.s_addr);
2946 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2947
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002948 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002949 nbr->ls_req_last = ospf_lsa_lock (lsa);
2950
2951 *length += 12;
2952 return 1;
2953}
2954
paul4dadc292005-05-06 21:37:42 +00002955static int
paul718e3742002-12-13 20:15:29 +00002956ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2957{
2958 struct ospf_lsa *lsa;
2959 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002960 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002961 struct route_table *table;
2962 struct route_node *rn;
2963 int i;
2964 struct ospf_lsdb *lsdb;
2965
2966 lsdb = &nbr->ls_req;
2967
2968 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2969 {
2970 table = lsdb->type[i].db;
2971 for (rn = route_top (table); rn; rn = route_next (rn))
2972 if ((lsa = (rn->info)) != NULL)
2973 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2974 {
2975 route_unlock_node (rn);
2976 break;
2977 }
2978 }
2979 return length;
2980}
2981
paul4dadc292005-05-06 21:37:42 +00002982static int
paul718e3742002-12-13 20:15:29 +00002983ls_age_increment (struct ospf_lsa *lsa, int delay)
2984{
2985 int age;
2986
2987 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2988
2989 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2990}
2991
paul4dadc292005-05-06 21:37:42 +00002992static int
hasso52dc7ee2004-09-23 19:18:23 +00002993ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002994{
2995 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002996 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002997 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00002998 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002999 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00003000 unsigned long pp;
3001 int count = 0;
3002
3003 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003004 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00003005
paul9985f832005-02-09 15:51:56 +00003006 pp = stream_get_endp (s);
3007 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003008 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00003009
gdt86f1fd92005-01-10 14:20:43 +00003010 /* Calculate amount of packet usable for data. */
3011 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3012
paul718e3742002-12-13 20:15:29 +00003013 while ((node = listhead (update)) != NULL)
3014 {
3015 struct lsa_header *lsah;
3016 u_int16_t ls_age;
3017
3018 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003019 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00003020
paul1eb8ef22005-04-07 07:30:20 +00003021 lsa = listgetdata (node);
3022
paul718e3742002-12-13 20:15:29 +00003023 assert (lsa->data);
3024
paul68b73392004-09-12 14:21:37 +00003025 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00003026 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00003027 break;
3028
paul718e3742002-12-13 20:15:29 +00003029 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00003030 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00003031
3032 /* Put LSA to Link State Request. */
3033 stream_put (s, lsa->data, ntohs (lsa->data->length));
3034
3035 /* Set LS age. */
3036 /* each hop must increment an lsa_age by transmit_delay
3037 of OSPF interface */
3038 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3039 lsah->ls_age = htons (ls_age);
3040
3041 length += ntohs (lsa->data->length);
3042 count++;
3043
3044 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003045 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003046 }
3047
3048 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00003049 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00003050
3051 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003052 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00003053 return length;
3054}
3055
paul4dadc292005-05-06 21:37:42 +00003056static int
hasso52dc7ee2004-09-23 19:18:23 +00003057ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00003058{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003059 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003060 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00003061 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00003062 struct ospf_lsa *lsa;
3063
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003064 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003065 {
paul718e3742002-12-13 20:15:29 +00003066 assert (lsa);
3067
gdt86f1fd92005-01-10 14:20:43 +00003068 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00003069 break;
3070
3071 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3072 length += OSPF_LSA_HEADER_SIZE;
3073
paul718e3742002-12-13 20:15:29 +00003074 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003075 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00003076 }
3077
paul718e3742002-12-13 20:15:29 +00003078 return length;
3079}
3080
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003081static void
3082ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
paul718e3742002-12-13 20:15:29 +00003083{
3084 struct ospf_packet *op;
3085 u_int16_t length = OSPF_HEADER_SIZE;
3086
3087 op = ospf_packet_new (oi->ifp->mtu);
3088
3089 /* Prepare OSPF common header. */
3090 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3091
3092 /* Prepare OSPF Hello body. */
3093 length += ospf_make_hello (oi, op->s);
3094
3095 /* Fill OSPF header. */
3096 ospf_fill_header (oi, op->s, length);
3097
3098 /* Set packet length. */
3099 op->length = length;
3100
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003101 op->dst.s_addr = addr;
paul718e3742002-12-13 20:15:29 +00003102
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003103 /* Add packet to the top of the interface output queue, so that they
3104 * can't get delayed by things like long queues of LS Update packets
3105 */
3106 ospf_packet_add_top (oi, op);
paul718e3742002-12-13 20:15:29 +00003107
3108 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003109 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003110}
3111
paul4dadc292005-05-06 21:37:42 +00003112static void
paul718e3742002-12-13 20:15:29 +00003113ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3114{
3115 struct ospf_interface *oi;
3116
3117 oi = nbr_nbma->oi;
3118 assert(oi);
3119
3120 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003121 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003122 return;
3123
3124 if (oi->type != OSPF_IFTYPE_NBMA)
3125 return;
3126
3127 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3128 return;
3129
3130 if (PRIORITY(oi) == 0)
3131 return;
3132
3133 if (nbr_nbma->priority == 0
3134 && oi->state != ISM_DR && oi->state != ISM_Backup)
3135 return;
3136
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003137 ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
paul718e3742002-12-13 20:15:29 +00003138}
3139
3140int
3141ospf_poll_timer (struct thread *thread)
3142{
3143 struct ospf_nbr_nbma *nbr_nbma;
3144
3145 nbr_nbma = THREAD_ARG (thread);
3146 nbr_nbma->t_poll = NULL;
3147
3148 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003149 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003150 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3151
3152 ospf_poll_send (nbr_nbma);
3153
3154 if (nbr_nbma->v_poll > 0)
3155 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3156 nbr_nbma->v_poll);
3157
3158 return 0;
3159}
3160
3161
3162int
3163ospf_hello_reply_timer (struct thread *thread)
3164{
3165 struct ospf_neighbor *nbr;
3166
3167 nbr = THREAD_ARG (thread);
3168 nbr->t_hello_reply = NULL;
3169
3170 assert (nbr->oi);
3171
3172 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003173 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003174 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3175
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003176 ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003177
3178 return 0;
3179}
3180
3181/* Send OSPF Hello. */
3182void
3183ospf_hello_send (struct ospf_interface *oi)
3184{
paul718e3742002-12-13 20:15:29 +00003185 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003186 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003187 return;
3188
paul718e3742002-12-13 20:15:29 +00003189 if (oi->type == OSPF_IFTYPE_NBMA)
3190 {
3191 struct ospf_neighbor *nbr;
3192 struct route_node *rn;
3193
3194 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3195 if ((nbr = rn->info))
3196 if (nbr != oi->nbr_self)
3197 if (nbr->state != NSM_Down)
3198 {
3199 /* RFC 2328 Section 9.5.1
3200 If the router is not eligible to become Designated Router,
3201 it must periodically send Hello Packets to both the
3202 Designated Router and the Backup Designated Router (if they
3203 exist). */
3204 if (PRIORITY(oi) == 0 &&
3205 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3206 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3207 continue;
3208
3209 /* If the router is eligible to become Designated Router, it
3210 must periodically send Hello Packets to all neighbors that
3211 are also eligible. In addition, if the router is itself the
3212 Designated Router or Backup Designated Router, it must also
3213 send periodic Hello Packets to all other neighbors. */
3214
3215 if (nbr->priority == 0 && oi->state == ISM_DROther)
3216 continue;
3217 /* if oi->state == Waiting, send hello to all neighbors */
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003218 ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
paul718e3742002-12-13 20:15:29 +00003219 }
paul718e3742002-12-13 20:15:29 +00003220 }
3221 else
3222 {
3223 /* Decide destination address. */
3224 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
Paul Jakmaaa276fd2010-01-08 17:11:15 +00003225 ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3226 else
3227 ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
paul718e3742002-12-13 20:15:29 +00003228 }
3229}
3230
3231/* Send OSPF Database Description. */
3232void
3233ospf_db_desc_send (struct ospf_neighbor *nbr)
3234{
3235 struct ospf_interface *oi;
3236 struct ospf_packet *op;
3237 u_int16_t length = OSPF_HEADER_SIZE;
3238
3239 oi = nbr->oi;
3240 op = ospf_packet_new (oi->ifp->mtu);
3241
3242 /* Prepare OSPF common header. */
3243 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3244
3245 /* Prepare OSPF Database Description body. */
3246 length += ospf_make_db_desc (oi, nbr, op->s);
3247
3248 /* Fill OSPF header. */
3249 ospf_fill_header (oi, op->s, length);
3250
3251 /* Set packet length. */
3252 op->length = length;
3253
3254 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003255 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3256 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3257 else
3258 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003259
3260 /* Add packet to the interface output queue. */
3261 ospf_packet_add (oi, op);
3262
3263 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003264 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003265
3266 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3267 if (nbr->last_send)
3268 ospf_packet_free (nbr->last_send);
3269 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003270 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003271}
3272
3273/* Re-send Database Description. */
3274void
3275ospf_db_desc_resend (struct ospf_neighbor *nbr)
3276{
3277 struct ospf_interface *oi;
3278
3279 oi = nbr->oi;
3280
3281 /* Add packet to the interface output queue. */
3282 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3283
3284 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003285 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003286}
3287
3288/* Send Link State Request. */
3289void
3290ospf_ls_req_send (struct ospf_neighbor *nbr)
3291{
3292 struct ospf_interface *oi;
3293 struct ospf_packet *op;
3294 u_int16_t length = OSPF_HEADER_SIZE;
3295
3296 oi = nbr->oi;
3297 op = ospf_packet_new (oi->ifp->mtu);
3298
3299 /* Prepare OSPF common header. */
3300 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3301
3302 /* Prepare OSPF Link State Request body. */
3303 length += ospf_make_ls_req (nbr, op->s);
3304 if (length == OSPF_HEADER_SIZE)
3305 {
3306 ospf_packet_free (op);
3307 return;
3308 }
3309
3310 /* Fill OSPF header. */
3311 ospf_fill_header (oi, op->s, length);
3312
3313 /* Set packet length. */
3314 op->length = length;
3315
3316 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003317 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3318 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3319 else
3320 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003321
3322 /* Add packet to the interface output queue. */
3323 ospf_packet_add (oi, op);
3324
3325 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003326 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003327
3328 /* Add Link State Request Retransmission Timer. */
3329 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3330}
3331
3332/* Send Link State Update with an LSA. */
3333void
3334ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3335 int flag)
3336{
hasso52dc7ee2004-09-23 19:18:23 +00003337 struct list *update;
paul718e3742002-12-13 20:15:29 +00003338
3339 update = list_new ();
3340
3341 listnode_add (update, lsa);
3342 ospf_ls_upd_send (nbr, update, flag);
3343
3344 list_delete (update);
3345}
3346
paul68b73392004-09-12 14:21:37 +00003347/* Determine size for packet. Must be at least big enough to accomodate next
3348 * LSA on list, which may be bigger than MTU size.
3349 *
3350 * Return pointer to new ospf_packet
3351 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3352 * on packet sizes (in which case offending LSA is deleted from update list)
3353 */
3354static struct ospf_packet *
3355ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3356{
3357 struct ospf_lsa *lsa;
3358 struct listnode *ln;
3359 size_t size;
3360 static char warned = 0;
3361
paul1eb8ef22005-04-07 07:30:20 +00003362 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003363 assert (lsa->data);
3364
3365 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3366 > ospf_packet_max (oi))
3367 {
3368 if (!warned)
3369 {
3370 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3371 "will need to fragment. Not optimal. Try divide up"
3372 " your network with areas. Use 'debug ospf packet send'"
3373 " to see details, or look at 'show ip ospf database ..'");
3374 warned = 1;
3375 }
3376
3377 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003378 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003379 " %d bytes originated by %s, will be fragmented!",
3380 inet_ntoa (lsa->data->id),
3381 ntohs (lsa->data->length),
3382 inet_ntoa (lsa->data->adv_router));
3383
3384 /*
3385 * Allocate just enough to fit this LSA only, to avoid including other
3386 * LSAs in fragmented LSA Updates.
3387 */
3388 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3389 + OSPF_LS_UPD_MIN_SIZE;
3390 }
3391 else
3392 size = oi->ifp->mtu;
3393
3394 if (size > OSPF_MAX_PACKET_SIZE)
3395 {
3396 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003397 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003398 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003399 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003400 (long int) size);
paul68b73392004-09-12 14:21:37 +00003401 list_delete_node (update, ln);
3402 return NULL;
3403 }
3404
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003405 /* IP header is built up separately by ospf_write(). This means, that we must
3406 * reduce the "affordable" size just calculated by length of an IP header.
3407 * This makes sure, that even if we manage to fill the payload with LSA data
3408 * completely, the final packet (our data plus IP header) still fits into
3409 * outgoing interface MTU. This correction isn't really meaningful for an
3410 * oversized LSA, but for consistency the correction is done for both cases.
3411 *
3412 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3413 */
3414 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003415}
3416
paul718e3742002-12-13 20:15:29 +00003417static void
hasso52dc7ee2004-09-23 19:18:23 +00003418ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003419 struct in_addr addr)
3420{
3421 struct ospf_packet *op;
3422 u_int16_t length = OSPF_HEADER_SIZE;
3423
3424 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003425 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003426
3427 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003428
3429 /* Prepare OSPF common header. */
3430 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3431
paul59ea14c2004-07-14 20:50:36 +00003432 /* Prepare OSPF Link State Update body.
3433 * Includes Type-7 translation.
3434 */
paul718e3742002-12-13 20:15:29 +00003435 length += ospf_make_ls_upd (oi, update, op->s);
3436
3437 /* Fill OSPF header. */
3438 ospf_fill_header (oi, op->s, length);
3439
3440 /* Set packet length. */
3441 op->length = length;
3442
3443 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003444 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3445 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3446 else
3447 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003448
3449 /* Add packet to the interface output queue. */
3450 ospf_packet_add (oi, op);
3451
3452 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003453 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003454}
3455
3456static int
3457ospf_ls_upd_send_queue_event (struct thread *thread)
3458{
3459 struct ospf_interface *oi = THREAD_ARG(thread);
3460 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003461 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003462 struct list *update;
paul68b73392004-09-12 14:21:37 +00003463 char again = 0;
paul718e3742002-12-13 20:15:29 +00003464
3465 oi->t_ls_upd_event = NULL;
3466
3467 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003468 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003469
paul736d3442003-07-24 23:22:57 +00003470 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003471 {
paul736d3442003-07-24 23:22:57 +00003472 rnext = route_next (rn);
3473
paul718e3742002-12-13 20:15:29 +00003474 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003475 continue;
paul68b73392004-09-12 14:21:37 +00003476
3477 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003478
paul48fe13b2004-07-27 17:40:44 +00003479 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003480
paul68b73392004-09-12 14:21:37 +00003481 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003482 if (listcount(update) == 0)
3483 {
3484 list_delete (rn->info);
3485 rn->info = NULL;
3486 route_unlock_node (rn);
3487 }
3488 else
paul68b73392004-09-12 14:21:37 +00003489 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003490 }
3491
3492 if (again != 0)
3493 {
3494 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003495 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003496 " %d nodes to try again, raising new event", again);
3497 oi->t_ls_upd_event =
3498 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003499 }
3500
3501 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003502 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003503
paul718e3742002-12-13 20:15:29 +00003504 return 0;
3505}
3506
3507void
hasso52dc7ee2004-09-23 19:18:23 +00003508ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003509{
3510 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003511 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003512 struct prefix_ipv4 p;
3513 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003514 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003515
3516 oi = nbr->oi;
3517
3518 p.family = AF_INET;
3519 p.prefixlen = IPV4_MAX_BITLEN;
3520
3521 /* Decide destination address. */
3522 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3523 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003524 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3525 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003526 else if (flag == OSPF_SEND_PACKET_DIRECT)
3527 p.prefix = nbr->address.u.prefix4;
3528 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3529 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003530 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3531 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003532 else
3533 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3534
3535 if (oi->type == OSPF_IFTYPE_NBMA)
3536 {
3537 if (flag == OSPF_SEND_PACKET_INDIRECT)
3538 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3539 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3540 zlog_warn ("* LS-Update is sent to myself.");
3541 }
3542
3543 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3544
3545 if (rn->info == NULL)
3546 rn->info = list_new ();
3547
paul1eb8ef22005-04-07 07:30:20 +00003548 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003549 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003550
3551 if (oi->t_ls_upd_event == NULL)
3552 oi->t_ls_upd_event =
3553 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3554}
3555
3556static void
hasso52dc7ee2004-09-23 19:18:23 +00003557ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3558 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003559{
3560 struct ospf_packet *op;
3561 u_int16_t length = OSPF_HEADER_SIZE;
3562
3563 op = ospf_packet_new (oi->ifp->mtu);
3564
3565 /* Prepare OSPF common header. */
3566 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3567
3568 /* Prepare OSPF Link State Acknowledgment body. */
3569 length += ospf_make_ls_ack (oi, ack, op->s);
3570
3571 /* Fill OSPF header. */
3572 ospf_fill_header (oi, op->s, length);
3573
3574 /* Set packet length. */
3575 op->length = length;
3576
3577 /* Set destination IP address. */
3578 op->dst = dst;
3579
3580 /* Add packet to the interface output queue. */
3581 ospf_packet_add (oi, op);
3582
3583 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003584 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003585}
3586
3587static int
3588ospf_ls_ack_send_event (struct thread *thread)
3589{
3590 struct ospf_interface *oi = THREAD_ARG (thread);
3591
3592 oi->t_ls_ack_direct = NULL;
3593
3594 while (listcount (oi->ls_ack_direct.ls_ack))
3595 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3596 oi->ls_ack_direct.dst);
3597
3598 return 0;
3599}
3600
3601void
3602ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3603{
3604 struct ospf_interface *oi = nbr->oi;
3605
3606 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3607 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3608
3609 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3610
3611 if (oi->t_ls_ack_direct == NULL)
3612 oi->t_ls_ack_direct =
3613 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3614}
3615
3616/* Send Link State Acknowledgment delayed. */
3617void
3618ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3619{
3620 struct in_addr dst;
3621
3622 /* Decide destination address. */
3623 /* RFC2328 Section 13.5 On non-broadcast
3624 networks, delayed Link State Acknowledgment packets must be
3625 unicast separately over each adjacency (i.e., neighbor whose
3626 state is >= Exchange). */
3627 if (oi->type == OSPF_IFTYPE_NBMA)
3628 {
3629 struct ospf_neighbor *nbr;
3630 struct route_node *rn;
3631
3632 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3633 if ((nbr = rn->info) != NULL)
3634 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3635 while (listcount (oi->ls_ack))
3636 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3637 return;
3638 }
3639 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3640 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3641 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3642 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3643 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3644 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003645 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3646 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003647 else
3648 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3649
3650 while (listcount (oi->ls_ack))
3651 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3652}