Annotation of embedaddon/quagga/ospfd/ospf_packet.c, revision 1.1.1.5
1.1 misho 1: /*
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"
34: #include "sockopt.h"
35: #include "checksum.h"
36: #include "md5.h"
37:
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:
52: /* Packet Type String. */
1.1.1.2 misho 53: const struct message ospf_packet_type_str[] =
1.1 misho 54: {
1.1.1.2 misho 55: { 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" },
1.1 misho 60: };
1.1.1.2 misho 61: const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) /
62: sizeof (ospf_packet_type_str[0]);
63:
64: /* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
65: particular types, offset is the "type" field of a packet. */
66: static 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:
76: /* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular
77: types, offset is the "LSA type" field. */
78: static const u_int16_t ospf_lsa_minlen[] =
79: {
80: 0,
81: OSPF_ROUTER_LSA_MIN_SIZE,
82: OSPF_NETWORK_LSA_MIN_SIZE,
83: OSPF_SUMMARY_LSA_MIN_SIZE,
84: OSPF_SUMMARY_LSA_MIN_SIZE,
85: OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
86: 0,
87: OSPF_AS_EXTERNAL_LSA_MIN_SIZE,
88: 0,
89: 0,
90: 0,
91: 0,
92: };
93:
94: /* for ospf_check_auth() */
95: static int ospf_check_sum (struct ospf_header *);
1.1 misho 96:
97: /* OSPF authentication checking function */
98: static int
99: ospf_auth_type (struct ospf_interface *oi)
100: {
101: int auth_type;
102:
103: if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
104: auth_type = oi->area->auth_type;
105: else
106: auth_type = OSPF_IF_PARAM (oi, auth_type);
107:
108: /* Handle case where MD5 key list is not configured aka Cisco */
109: if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
110: list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
111: return OSPF_AUTH_NULL;
112:
113: return auth_type;
114:
115: }
116:
117: struct ospf_packet *
118: ospf_packet_new (size_t size)
119: {
120: struct ospf_packet *new;
121:
122: new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
123: new->s = stream_new (size);
124:
125: return new;
126: }
127:
128: void
129: ospf_packet_free (struct ospf_packet *op)
130: {
131: if (op->s)
132: stream_free (op->s);
133:
134: XFREE (MTYPE_OSPF_PACKET, op);
135:
136: op = NULL;
137: }
138:
139: struct ospf_fifo *
140: ospf_fifo_new ()
141: {
142: struct ospf_fifo *new;
143:
144: new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
145: return new;
146: }
147:
148: /* Add new packet to fifo. */
149: void
150: ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
151: {
152: if (fifo->tail)
153: fifo->tail->next = op;
154: else
155: fifo->head = op;
156:
157: fifo->tail = op;
158:
159: fifo->count++;
160: }
161:
162: /* Add new packet to head of fifo. */
163: static void
164: ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
165: {
166: op->next = fifo->head;
167:
168: if (fifo->tail == NULL)
169: fifo->tail = op;
170:
171: fifo->head = op;
172:
173: fifo->count++;
174: }
175:
176: /* Delete first packet from fifo. */
177: struct ospf_packet *
178: ospf_fifo_pop (struct ospf_fifo *fifo)
179: {
180: struct ospf_packet *op;
181:
182: op = fifo->head;
183:
184: if (op)
185: {
186: fifo->head = op->next;
187:
188: if (fifo->head == NULL)
189: fifo->tail = NULL;
190:
191: fifo->count--;
192: }
193:
194: return op;
195: }
196:
197: /* Return first fifo entry. */
198: struct ospf_packet *
199: ospf_fifo_head (struct ospf_fifo *fifo)
200: {
201: return fifo->head;
202: }
203:
204: /* Flush ospf packet fifo. */
205: void
206: ospf_fifo_flush (struct ospf_fifo *fifo)
207: {
208: struct ospf_packet *op;
209: struct ospf_packet *next;
210:
211: for (op = fifo->head; op; op = next)
212: {
213: next = op->next;
214: ospf_packet_free (op);
215: }
216: fifo->head = fifo->tail = NULL;
217: fifo->count = 0;
218: }
219:
220: /* Free ospf packet fifo. */
221: void
222: ospf_fifo_free (struct ospf_fifo *fifo)
223: {
224: ospf_fifo_flush (fifo);
225:
226: XFREE (MTYPE_OSPF_FIFO, fifo);
227: }
228:
229: void
230: ospf_packet_add (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),
1.1.1.2 misho 238: LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
1.1 misho 239: inet_ntoa (op->dst));
240: return;
241: }
242:
243: /* Add packet to end of queue. */
244: ospf_fifo_push (oi->obuf, op);
245:
246: /* Debug of packet fifo*/
247: /* ospf_fifo_debug (oi->obuf); */
248: }
249:
250: static void
251: ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
252: {
253: if (!oi->obuf)
254: {
255: zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
256: "destination %s) called with NULL obuf, ignoring "
257: "(please report this bug)!\n",
258: IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
1.1.1.2 misho 259: LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),
1.1 misho 260: inet_ntoa (op->dst));
261: return;
262: }
263:
264: /* Add packet to head of queue. */
265: ospf_fifo_push_head (oi->obuf, op);
266:
267: /* Debug of packet fifo*/
268: /* ospf_fifo_debug (oi->obuf); */
269: }
270:
271: void
272: ospf_packet_delete (struct ospf_interface *oi)
273: {
274: struct ospf_packet *op;
275:
276: op = ospf_fifo_pop (oi->obuf);
277:
278: if (op)
279: ospf_packet_free (op);
280: }
281:
282: struct ospf_packet *
283: ospf_packet_dup (struct ospf_packet *op)
284: {
285: struct ospf_packet *new;
286:
287: if (stream_get_endp(op->s) != op->length)
288: /* XXX size_t */
289: zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
290: (u_long)STREAM_SIZE(op->s), op->length);
291:
292: /* Reserve space for MD5 authentication that may be added later. */
293: new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
294: stream_copy (new->s, op->s);
295:
296: new->dst = op->dst;
297: new->length = op->length;
298:
299: return new;
300: }
301:
302: /* XXX inline */
1.1.1.3 misho 303: static unsigned int
1.1 misho 304: ospf_packet_authspace (struct ospf_interface *oi)
305: {
306: int auth = 0;
307:
308: if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
309: auth = OSPF_AUTH_MD5_SIZE;
310:
311: return auth;
312: }
313:
314: static unsigned int
315: ospf_packet_max (struct ospf_interface *oi)
316: {
317: int max;
318:
319: max = oi->ifp->mtu - ospf_packet_authspace(oi);
320:
321: max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
322:
323: return max;
324: }
325:
1.1.1.5 ! misho 326:
1.1 misho 327: static int
1.1.1.2 misho 328: ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)
1.1 misho 329: {
330: MD5_CTX ctx;
331: unsigned char digest[OSPF_AUTH_MD5_SIZE];
332: struct crypt_key *ck;
333: struct ospf_neighbor *nbr;
1.1.1.2 misho 334: u_int16_t length = ntohs (ospfh->length);
1.1 misho 335:
336: /* Get secret key. */
337: ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
338: ospfh->u.crypt.key_id);
339: if (ck == NULL)
340: {
341: zlog_warn ("interface %s: ospf_check_md5 no key %d",
342: IF_NAME (oi), ospfh->u.crypt.key_id);
343: return 0;
344: }
345:
346: /* check crypto seqnum. */
347: nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
348:
349: if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
350: {
351: zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
352: IF_NAME (oi),
353: ntohl(ospfh->u.crypt.crypt_seqnum),
354: ntohl(nbr->crypt_seqnum));
355: return 0;
356: }
357:
358: /* Generate a digest for the ospf packet - their digest + our digest. */
359: memset(&ctx, 0, sizeof(ctx));
360: MD5Init(&ctx);
1.1.1.2 misho 361: MD5Update(&ctx, ospfh, length);
1.1 misho 362: MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
363: MD5Final(digest, &ctx);
364:
365: /* compare the two */
1.1.1.2 misho 366: if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))
1.1 misho 367: {
368: zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
369: IF_NAME (oi));
370: return 0;
371: }
372:
373: /* save neighbor's crypt_seqnum */
374: if (nbr)
375: nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
376: return 1;
377: }
378:
379: /* This function is called from ospf_write(), it will detect the
380: authentication scheme and if it is MD5, it will change the sequence
381: and update the MD5 digest. */
382: static int
383: ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
384: {
385: struct ospf_header *ospfh;
1.1.1.5 ! misho 386: unsigned char digest[OSPF_AUTH_MD5_SIZE] = {0};
1.1 misho 387: MD5_CTX ctx;
388: void *ibuf;
389: u_int32_t t;
390: struct crypt_key *ck;
391: const u_int8_t *auth_key;
392:
393: ibuf = STREAM_DATA (op->s);
394: ospfh = (struct ospf_header *) ibuf;
395:
396: if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
397: return 0;
398:
399: /* We do this here so when we dup a packet, we don't have to
400: waste CPU rewriting other headers.
401:
402: Note that quagga_time /deliberately/ is not used here */
403: t = (time(NULL) & 0xFFFFFFFF);
404: if (t > oi->crypt_seqnum)
405: oi->crypt_seqnum = t;
406: else
407: oi->crypt_seqnum++;
408:
409: ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
410:
411: /* Get MD5 Authentication key from auth_key list. */
412: if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
1.1.1.5 ! misho 413: auth_key = (const u_int8_t *) digest;
1.1 misho 414: else
415: {
416: ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
417: auth_key = ck->auth_key;
418: }
419:
420: /* Generate a digest for the entire packet + our secret key. */
421: memset(&ctx, 0, sizeof(ctx));
422: MD5Init(&ctx);
423: MD5Update(&ctx, ibuf, ntohs (ospfh->length));
424: MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
425: MD5Final(digest, &ctx);
426:
427: /* Append md5 digest to the end of the stream. */
428: stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
429:
430: /* We do *NOT* increment the OSPF header length. */
431: op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
432:
433: if (stream_get_endp(op->s) != op->length)
434: /* XXX size_t */
435: zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
436: (u_long)stream_get_endp(op->s), op->length);
437:
438: return OSPF_AUTH_MD5_SIZE;
439: }
440:
1.1.1.5 ! misho 441:
1.1 misho 442: static int
443: ospf_ls_req_timer (struct thread *thread)
444: {
445: struct ospf_neighbor *nbr;
446:
447: nbr = THREAD_ARG (thread);
448: nbr->t_ls_req = NULL;
449:
450: /* Send Link State Request. */
451: if (ospf_ls_request_count (nbr))
452: ospf_ls_req_send (nbr);
453:
454: /* Set Link State Request retransmission timer. */
455: OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
456:
457: return 0;
458: }
459:
460: void
461: ospf_ls_req_event (struct ospf_neighbor *nbr)
462: {
463: if (nbr->t_ls_req)
464: {
465: thread_cancel (nbr->t_ls_req);
466: nbr->t_ls_req = NULL;
467: }
468: nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
469: }
470:
471: /* Cyclic timer function. Fist registered in ospf_nbr_new () in
472: ospf_neighbor.c */
473: int
474: ospf_ls_upd_timer (struct thread *thread)
475: {
476: struct ospf_neighbor *nbr;
477:
478: nbr = THREAD_ARG (thread);
479: nbr->t_ls_upd = NULL;
480:
481: /* Send Link State Update. */
482: if (ospf_ls_retransmit_count (nbr) > 0)
483: {
484: struct list *update;
485: struct ospf_lsdb *lsdb;
486: int i;
487: int retransmit_interval;
488:
489: retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
490:
491: lsdb = &nbr->ls_rxmt;
492: update = list_new ();
493:
494: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
495: {
496: struct route_table *table = lsdb->type[i].db;
497: struct route_node *rn;
498:
499: for (rn = route_top (table); rn; rn = route_next (rn))
500: {
501: struct ospf_lsa *lsa;
502:
503: if ((lsa = rn->info) != NULL)
504: /* Don't retransmit an LSA if we received it within
505: the last RxmtInterval seconds - this is to allow the
506: neighbour a chance to acknowledge the LSA as it may
507: have ben just received before the retransmit timer
508: fired. This is a small tweak to what is in the RFC,
509: but it will cut out out a lot of retransmit traffic
510: - MAG */
511: if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
512: int2tv (retransmit_interval)) >= 0)
513: listnode_add (update, rn->info);
514: }
515: }
516:
517: if (listcount (update) > 0)
518: ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
519: list_delete (update);
520: }
521:
522: /* Set LS Update retransmission timer. */
523: OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
524:
525: return 0;
526: }
527:
528: int
529: ospf_ls_ack_timer (struct thread *thread)
530: {
531: struct ospf_interface *oi;
532:
533: oi = THREAD_ARG (thread);
534: oi->t_ls_ack = NULL;
535:
536: /* Send Link State Acknowledgment. */
537: if (listcount (oi->ls_ack) > 0)
538: ospf_ls_ack_send_delayed (oi);
539:
540: /* Set LS Ack timer. */
541: OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
542:
543: return 0;
544: }
545:
546: #ifdef WANT_OSPF_WRITE_FRAGMENT
547: static void
548: ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
549: struct msghdr *msg, unsigned int maxdatasize,
550: unsigned int mtu, int flags, u_char type)
551: {
552: #define OSPF_WRITE_FRAG_SHIFT 3
553: u_int16_t offset;
554: struct iovec *iovp;
555: int ret;
556:
557: assert ( op->length == stream_get_endp(op->s) );
558: assert (msg->msg_iovlen == 2);
559:
560: /* we can but try.
561: *
562: * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
563: * well as the IP_MF flag, making this all quite pointless.
564: *
565: * However, for a system on which IP_MF is left alone, and ip_id left
566: * alone or else which sets same ip_id for each fragment this might
567: * work, eg linux.
568: *
569: * XXX-TODO: It would be much nicer to have the kernel's use their
570: * existing fragmentation support to do this for us. Bugs/RFEs need to
571: * be raised against the various kernels.
572: */
573:
574: /* set More Frag */
575: iph->ip_off |= IP_MF;
576:
577: /* ip frag offset is expressed in units of 8byte words */
578: offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
579:
580: iovp = &msg->msg_iov[1];
581:
582: while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
583: > maxdatasize )
584: {
585: /* data length of this frag is to next offset value */
586: iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
587: iph->ip_len = iovp->iov_len + sizeof (struct ip);
588: assert (iph->ip_len <= mtu);
589:
590: sockopt_iphdrincl_swab_htosys (iph);
591:
592: ret = sendmsg (fd, msg, flags);
593:
594: sockopt_iphdrincl_swab_systoh (iph);
595:
596: if (ret < 0)
597: zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
598: " id %d, off %d, len %d, mtu %u failed with %s",
599: inet_ntoa (iph->ip_dst),
600: iph->ip_id,
601: iph->ip_off,
602: iph->ip_len,
603: mtu,
604: safe_strerror (errno));
605:
606: if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
607: {
608: zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
609: iph->ip_id, iph->ip_off, iph->ip_len,
610: inet_ntoa (iph->ip_dst));
611: if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
612: {
613: zlog_debug ("-----------------IP Header Dump----------------------");
614: ospf_ip_header_dump (iph);
615: zlog_debug ("-----------------------------------------------------");
616: }
617: }
618:
619: iph->ip_off += offset;
620: stream_forward_getp (op->s, iovp->iov_len);
621: iovp->iov_base = STREAM_PNT (op->s);
622: }
623:
624: /* setup for final fragment */
625: iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
626: iph->ip_len = iovp->iov_len + sizeof (struct ip);
627: iph->ip_off &= (~IP_MF);
628: }
629: #endif /* WANT_OSPF_WRITE_FRAGMENT */
630:
631: static int
632: ospf_write (struct thread *thread)
633: {
634: struct ospf *ospf = THREAD_ARG (thread);
635: struct ospf_interface *oi;
636: struct ospf_packet *op;
637: struct sockaddr_in sa_dst;
638: struct ip iph;
639: struct msghdr msg;
640: struct iovec iov[2];
641: u_char type;
642: int ret;
643: int flags = 0;
644: struct listnode *node;
645: #ifdef WANT_OSPF_WRITE_FRAGMENT
646: static u_int16_t ipid = 0;
647: u_int16_t maxdatasize;
1.1.1.5 ! misho 648: #endif /* WANT_OSPF_WRITE_FRAGMENT */
1.1 misho 649: #define OSPF_WRITE_IPHL_SHIFT 2
650:
651: ospf->t_write = NULL;
652:
653: node = listhead (ospf->oi_write_q);
654: assert (node);
655: oi = listgetdata (node);
656: assert (oi);
657:
658: #ifdef WANT_OSPF_WRITE_FRAGMENT
659: /* seed ipid static with low order bits of time */
660: if (ipid == 0)
661: ipid = (time(NULL) & 0xffff);
662:
663: /* convenience - max OSPF data per packet,
664: * and reliability - not more data, than our
665: * socket can accept
666: */
667: maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
668: sizeof (struct ip);
1.1.1.5 ! misho 669: #endif /* WANT_OSPF_WRITE_FRAGMENT */
1.1 misho 670:
671: /* Get one packet from queue. */
672: op = ospf_fifo_head (oi->obuf);
673: assert (op);
674: assert (op->length >= OSPF_HEADER_SIZE);
675:
676: if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
677: || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
678: ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
679:
680: /* Rewrite the md5 signature & update the seq */
681: ospf_make_md5_digest (oi, op);
682:
683: /* Retrieve OSPF packet type. */
684: stream_set_getp (op->s, 1);
685: type = stream_getc (op->s);
686:
687: /* reset get pointer */
688: stream_set_getp (op->s, 0);
689:
690: memset (&iph, 0, sizeof (struct ip));
691: memset (&sa_dst, 0, sizeof (sa_dst));
692:
693: sa_dst.sin_family = AF_INET;
694: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
695: sa_dst.sin_len = sizeof(sa_dst);
696: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
697: sa_dst.sin_addr = op->dst;
698: sa_dst.sin_port = htons (0);
699:
700: /* Set DONTROUTE flag if dst is unicast. */
701: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
702: if (!IN_MULTICAST (htonl (op->dst.s_addr)))
703: flags = MSG_DONTROUTE;
704:
705: iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
706: /* it'd be very strange for header to not be 4byte-word aligned but.. */
707: if ( sizeof (struct ip)
708: > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
709: iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
710:
711: iph.ip_v = IPVERSION;
712: iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
713: iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
714:
715: #if defined(__DragonFly__)
716: /*
717: * DragonFly's raw socket expects ip_len/ip_off in network byte order.
718: */
719: iph.ip_len = htons(iph.ip_len);
720: #endif
721:
722: #ifdef WANT_OSPF_WRITE_FRAGMENT
723: /* XXX-MT: not thread-safe at all..
724: * XXX: this presumes this is only programme sending OSPF packets
725: * otherwise, no guarantee ipid will be unique
726: */
727: iph.ip_id = ++ipid;
728: #endif /* WANT_OSPF_WRITE_FRAGMENT */
729:
730: iph.ip_off = 0;
731: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
732: iph.ip_ttl = OSPF_VL_IP_TTL;
733: else
734: iph.ip_ttl = OSPF_IP_TTL;
735: iph.ip_p = IPPROTO_OSPFIGP;
736: iph.ip_sum = 0;
737: iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
738: iph.ip_dst.s_addr = op->dst.s_addr;
739:
740: memset (&msg, 0, sizeof (msg));
741: msg.msg_name = (caddr_t) &sa_dst;
742: msg.msg_namelen = sizeof (sa_dst);
743: msg.msg_iov = iov;
744: msg.msg_iovlen = 2;
745: iov[0].iov_base = (char*)&iph;
746: iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
747: iov[1].iov_base = STREAM_PNT (op->s);
748: iov[1].iov_len = op->length;
749:
750: /* Sadly we can not rely on kernels to fragment packets because of either
751: * IP_HDRINCL and/or multicast destination being set.
752: */
753: #ifdef WANT_OSPF_WRITE_FRAGMENT
754: if ( op->length > maxdatasize )
755: ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
756: oi->ifp->mtu, flags, type);
757: #endif /* WANT_OSPF_WRITE_FRAGMENT */
758:
759: /* send final fragment (could be first) */
760: sockopt_iphdrincl_swab_htosys (&iph);
761: ret = sendmsg (ospf->fd, &msg, flags);
762: sockopt_iphdrincl_swab_systoh (&iph);
763:
764: if (ret < 0)
765: zlog_warn ("*** sendmsg in ospf_write failed to %s, "
766: "id %d, off %d, len %d, interface %s, mtu %u: %s",
767: inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
768: oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
769:
770: /* Show debug sending packet. */
771: if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
772: {
773: if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
774: {
775: zlog_debug ("-----------------------------------------------------");
776: ospf_ip_header_dump (&iph);
777: stream_set_getp (op->s, 0);
778: ospf_packet_dump (op->s);
779: }
780:
781: zlog_debug ("%s sent to [%s] via [%s].",
1.1.1.2 misho 782: LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),
1.1 misho 783: IF_NAME (oi));
784:
785: if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
786: zlog_debug ("-----------------------------------------------------");
787: }
788:
789: /* Now delete packet from queue. */
790: ospf_packet_delete (oi);
791:
1.1.1.5 ! misho 792: /* Move this interface to the tail of write_q to
! 793: serve everyone in a round robin fashion */
! 794: listnode_move_to_tail (ospf->oi_write_q, node);
1.1 misho 795: if (ospf_fifo_head (oi->obuf) == NULL)
796: {
797: oi->on_write_q = 0;
798: list_delete_node (ospf->oi_write_q, node);
799: }
800:
801: /* If packets still remain in queue, call write thread. */
802: if (!list_isempty (ospf->oi_write_q))
803: ospf->t_write =
804: thread_add_write (master, ospf_write, ospf, ospf->fd);
805:
806: return 0;
807: }
808:
809: /* OSPF Hello message read -- RFC2328 Section 10.5. */
810: static void
811: ospf_hello (struct ip *iph, struct ospf_header *ospfh,
812: struct stream * s, struct ospf_interface *oi, int size)
813: {
814: struct ospf_hello *hello;
815: struct ospf_neighbor *nbr;
816: int old_state;
817: struct prefix p;
818:
819: /* increment statistics. */
820: oi->hello_in++;
821:
822: hello = (struct ospf_hello *) STREAM_PNT (s);
823:
824: /* If Hello is myself, silently discard. */
825: if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
826: {
827: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
828: {
829: zlog_debug ("ospf_header[%s/%s]: selforiginated, "
830: "dropping.",
1.1.1.2 misho 831: LOOKUP (ospf_packet_type_str, ospfh->type),
1.1 misho 832: inet_ntoa (iph->ip_src));
833: }
834: return;
835: }
836:
837: /* get neighbor prefix. */
838: p.family = AF_INET;
839: p.prefixlen = ip_masklen (hello->network_mask);
840: p.u.prefix4 = iph->ip_src;
841:
842: /* Compare network mask. */
843: /* Checking is ignored for Point-to-Point and Virtual link. */
844: if (oi->type != OSPF_IFTYPE_POINTOPOINT
845: && oi->type != OSPF_IFTYPE_VIRTUALLINK)
846: if (oi->address->prefixlen != p.prefixlen)
847: {
848: zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
849: inet_ntoa(ospfh->router_id), IF_NAME(oi),
850: (int)oi->address->prefixlen, (int)p.prefixlen);
851: return;
852: }
853:
854: /* Compare Router Dead Interval. */
855: if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
856: {
857: zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
858: "(expected %u, but received %u).",
859: inet_ntoa(ospfh->router_id),
860: OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
861: return;
862: }
863:
864: /* Compare Hello Interval - ignored if fast-hellos are set. */
865: if (OSPF_IF_PARAM (oi, fast_hello) == 0)
866: {
867: if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
868: {
869: zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
870: "(expected %u, but received %u).",
871: inet_ntoa(ospfh->router_id),
872: OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
873: return;
874: }
875: }
876:
877: if (IS_DEBUG_OSPF_EVENT)
878: zlog_debug ("Packet %s [Hello:RECV]: Options %s",
879: inet_ntoa (ospfh->router_id),
880: ospf_options_dump (hello->options));
881:
882: /* Compare options. */
883: #define REJECT_IF_TBIT_ON 1 /* XXX */
884: #ifdef REJECT_IF_TBIT_ON
885: if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
886: {
887: /*
888: * This router does not support non-zero TOS.
889: * Drop this Hello packet not to establish neighbor relationship.
890: */
891: zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
892: inet_ntoa (ospfh->router_id));
893: return;
894: }
895: #endif /* REJECT_IF_TBIT_ON */
896:
897: if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
898: && CHECK_FLAG (hello->options, OSPF_OPTION_O))
899: {
900: /*
901: * This router does know the correct usage of O-bit
902: * the bit should be set in DD packet only.
903: */
904: zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
905: inet_ntoa (ospfh->router_id));
906: #ifdef STRICT_OBIT_USAGE_CHECK
907: return; /* Reject this packet. */
908: #else /* STRICT_OBIT_USAGE_CHECK */
909: UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
910: #endif /* STRICT_OBIT_USAGE_CHECK */
911: }
912:
913: /* new for NSSA is to ensure that NP is on and E is off */
914:
915: if (oi->area->external_routing == OSPF_AREA_NSSA)
916: {
917: if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
918: && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
919: && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
920: && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
921: {
922: zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
923: return;
924: }
925: if (IS_DEBUG_OSPF_NSSA)
926: zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
927: }
928: else
929: /* The setting of the E-bit found in the Hello Packet's Options
930: field must match this area's ExternalRoutingCapability A
931: mismatch causes processing to stop and the packet to be
932: dropped. The setting of the rest of the bits in the Hello
933: Packet's Options field should be ignored. */
934: if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
935: CHECK_FLAG (hello->options, OSPF_OPTION_E))
936: {
937: zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
938: inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
939: return;
940: }
941:
942: /* get neighbour struct */
943: nbr = ospf_nbr_get (oi, ospfh, iph, &p);
944:
945: /* neighbour must be valid, ospf_nbr_get creates if none existed */
946: assert (nbr);
947:
948: old_state = nbr->state;
949:
950: /* Add event to thread. */
951: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
952:
953: /* RFC2328 Section 9.5.1
954: If the router is not eligible to become Designated Router,
955: (snip) It must also send an Hello Packet in reply to an
956: Hello Packet received from any eligible neighbor (other than
957: the current Designated Router and Backup Designated Router). */
958: if (oi->type == OSPF_IFTYPE_NBMA)
959: if (PRIORITY(oi) == 0 && hello->priority > 0
960: && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
961: && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
962: OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
963: OSPF_HELLO_REPLY_DELAY);
964:
965: /* on NBMA network type, it happens to receive bidirectional Hello packet
966: without advance 1-Way Received event.
967: To avoid incorrect DR-seletion, raise 1-Way Received event.*/
968: if (oi->type == OSPF_IFTYPE_NBMA &&
969: (old_state == NSM_Down || old_state == NSM_Attempt))
970: {
971: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
972: nbr->priority = hello->priority;
973: nbr->d_router = hello->d_router;
974: nbr->bd_router = hello->bd_router;
975: return;
976: }
977:
978: if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
979: size - OSPF_HELLO_MIN_SIZE))
980: {
981: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
982: nbr->options |= hello->options;
983: }
984: else
985: {
986: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
987: /* Set neighbor information. */
988: nbr->priority = hello->priority;
989: nbr->d_router = hello->d_router;
990: nbr->bd_router = hello->bd_router;
991: return;
992: }
993:
994: /* If neighbor itself declares DR and no BDR exists,
995: cause event BackupSeen */
996: if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
997: if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
998: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
999:
1000: /* neighbor itself declares BDR. */
1001: if (oi->state == ISM_Waiting &&
1002: IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
1003: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
1004:
1005: /* had not previously. */
1006: if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
1007: IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
1008: (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
1009: IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
1010: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1011:
1012: /* had not previously. */
1013: if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
1014: IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
1015: (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
1016: IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
1017: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1018:
1019: /* Neighbor priority check. */
1020: if (nbr->priority >= 0 && nbr->priority != hello->priority)
1021: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
1022:
1023: /* Set neighbor information. */
1024: nbr->priority = hello->priority;
1025: nbr->d_router = hello->d_router;
1026: nbr->bd_router = hello->bd_router;
1027: }
1028:
1029: /* Save DD flags/options/Seqnum received. */
1030: static void
1031: ospf_db_desc_save_current (struct ospf_neighbor *nbr,
1032: struct ospf_db_desc *dd)
1033: {
1034: nbr->last_recv.flags = dd->flags;
1035: nbr->last_recv.options = dd->options;
1036: nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
1037: }
1038:
1039: /* Process rest of DD packet. */
1040: static void
1041: ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
1042: struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
1043: u_int16_t size)
1044: {
1045: struct ospf_lsa *new, *find;
1046: struct lsa_header *lsah;
1047:
1048: stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
1049: for (size -= OSPF_DB_DESC_MIN_SIZE;
1050: size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1051: {
1052: lsah = (struct lsa_header *) STREAM_PNT (s);
1053: stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
1054:
1055: /* Unknown LS type. */
1056: if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1057: {
1058: zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
1059: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1060: return;
1061: }
1062:
1063: if (IS_OPAQUE_LSA (lsah->type)
1064: && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1065: {
1066: zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1067: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1068: return;
1069: }
1070:
1071: switch (lsah->type)
1072: {
1073: case OSPF_AS_EXTERNAL_LSA:
1074: case OSPF_OPAQUE_AS_LSA:
1075: /* Check for stub area. Reject if AS-External from stub but
1076: allow if from NSSA. */
1077: if (oi->area->external_routing == OSPF_AREA_STUB)
1078: {
1079: zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1080: lsah->type, inet_ntoa (lsah->id),
1081: (oi->area->external_routing == OSPF_AREA_STUB) ?\
1082: "STUB" : "NSSA");
1083: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1084: return;
1085: }
1086: break;
1087: default:
1088: break;
1089: }
1090:
1091: /* Create LS-request object. */
1092: new = ospf_ls_request_new (lsah);
1093:
1094: /* Lookup received LSA, then add LS request list. */
1095: find = ospf_lsa_lookup_by_header (oi->area, lsah);
1096:
1097: /* ospf_lsa_more_recent is fine with NULL pointers */
1098: switch (ospf_lsa_more_recent (find, new))
1099: {
1100: case -1:
1101: /* Neighbour has a more recent LSA, we must request it */
1102: ospf_ls_request_add (nbr, new);
1103: case 0:
1104: /* If we have a copy of this LSA, it's either less recent
1105: * and we're requesting it from neighbour (the case above), or
1106: * it's as recent and we both have same copy (this case).
1107: *
1108: * In neither of these two cases is there any point in
1109: * describing our copy of the LSA to the neighbour in a
1110: * DB-Summary packet, if we're still intending to do so.
1111: *
1112: * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1113: * backward compatible optimisation to OSPF DB Exchange /
1114: * DB Description process implemented here.
1115: */
1116: if (find)
1117: ospf_lsdb_delete (&nbr->db_sum, find);
1118: ospf_lsa_discard (new);
1119: break;
1120: default:
1121: /* We have the more recent copy, nothing specific to do:
1122: * - no need to request neighbours stale copy
1123: * - must leave DB summary list copy alone
1124: */
1125: if (IS_DEBUG_OSPF_EVENT)
1126: zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1127: "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1128: ospf_lsa_discard (new);
1129: }
1130: }
1131:
1132: /* Master */
1133: if (IS_SET_DD_MS (nbr->dd_flags))
1134: {
1135: nbr->dd_seqnum++;
1136:
1137: /* Both sides have no More, then we're done with Exchange */
1138: if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1139: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1140: else
1141: ospf_db_desc_send (nbr);
1142: }
1143: /* Slave */
1144: else
1145: {
1146: nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1147:
1148: /* Send DD packet in reply.
1149: *
1150: * Must be done to acknowledge the Master's DD, regardless of
1151: * whether we have more LSAs ourselves to describe.
1152: *
1153: * This function will clear the 'More' bit, if after this DD
1154: * we have no more LSAs to describe to the master..
1155: */
1156: ospf_db_desc_send (nbr);
1157:
1158: /* Slave can raise ExchangeDone now, if master is also done */
1159: if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1160: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1161: }
1162:
1163: /* Save received neighbor values from DD. */
1164: ospf_db_desc_save_current (nbr, dd);
1165: }
1166:
1167: static int
1168: ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1169: {
1170: /* Is DD duplicated? */
1171: if (dd->options == nbr->last_recv.options &&
1172: dd->flags == nbr->last_recv.flags &&
1173: dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1174: return 1;
1175:
1176: return 0;
1177: }
1178:
1179: /* OSPF Database Description message read -- RFC2328 Section 10.6. */
1180: static void
1181: ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1182: struct stream *s, struct ospf_interface *oi, u_int16_t size)
1183: {
1184: struct ospf_db_desc *dd;
1185: struct ospf_neighbor *nbr;
1186:
1187: /* Increment statistics. */
1188: oi->db_desc_in++;
1189:
1190: dd = (struct ospf_db_desc *) STREAM_PNT (s);
1191:
1192: nbr = ospf_nbr_lookup (oi, iph, ospfh);
1193: if (nbr == NULL)
1194: {
1195: zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1196: inet_ntoa (ospfh->router_id));
1197: return;
1198: }
1199:
1200: /* Check MTU. */
1201: if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1202: (ntohs (dd->mtu) > oi->ifp->mtu))
1203: {
1204: zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1205: inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1206: IF_NAME (oi), oi->ifp->mtu);
1207: return;
1208: }
1209:
1210: /*
1211: * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1212: * required. In fact at least JunOS sends DD packets with P bit clear.
1213: * Until proper solution is developped, this hack should help.
1214: *
1215: * Update: According to the RFCs, N bit is specified /only/ for Hello
1216: * options, unfortunately its use in DD options is not specified. Hence some
1217: * implementations follow E-bit semantics and set it in DD options, and some
1218: * treat it as unspecified and hence follow the directive "default for
1219: * options is clear", ie unset.
1220: *
1221: * Reset the flag, as ospfd follows E-bit semantics.
1222: */
1223: if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1224: && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1225: && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1226: {
1227: if (IS_DEBUG_OSPF_EVENT)
1228: zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
1229: inet_ntoa (nbr->router_id) );
1230: SET_FLAG (dd->options, OSPF_OPTION_NP);
1231: }
1232:
1233: #ifdef REJECT_IF_TBIT_ON
1234: if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1235: {
1236: /*
1237: * In Hello protocol, optional capability must have checked
1238: * to prevent this T-bit enabled router be my neighbor.
1239: */
1240: zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1241: return;
1242: }
1243: #endif /* REJECT_IF_TBIT_ON */
1244:
1245: if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
1246: && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
1247: {
1248: /*
1249: * This node is not configured to handle O-bit, for now.
1250: * Clear it to ignore unsupported capability proposed by neighbor.
1251: */
1252: UNSET_FLAG (dd->options, OSPF_OPTION_O);
1253: }
1254:
1255: /* Add event to thread. */
1256: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1257:
1258: /* Process DD packet by neighbor status. */
1259: switch (nbr->state)
1260: {
1261: case NSM_Down:
1262: case NSM_Attempt:
1263: case NSM_TwoWay:
1264: zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
1265: inet_ntoa(nbr->router_id),
1266: LOOKUP (ospf_nsm_state_msg, nbr->state));
1267: break;
1268: case NSM_Init:
1269: OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1270: /* If the new state is ExStart, the processing of the current
1271: packet should then continue in this new state by falling
1272: through to case ExStart below. */
1273: if (nbr->state != NSM_ExStart)
1274: break;
1275: case NSM_ExStart:
1276: /* Initial DBD */
1277: if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1278: (size == OSPF_DB_DESC_MIN_SIZE))
1279: {
1280: if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
1281: {
1282: /* We're Slave---obey */
1283: zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
1284: inet_ntoa(nbr->router_id));
1285: nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1286:
1287: /* Reset I/MS */
1288: UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
1289: }
1290: else
1291: {
1292: /* We're Master, ignore the initial DBD from Slave */
1293: zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1294: "ignoring.", inet_ntoa(nbr->router_id));
1295: break;
1296: }
1297: }
1298: /* Ack from the Slave */
1299: else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1300: ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
1301: IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
1302: {
1303: zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
1304: inet_ntoa(nbr->router_id));
1305: /* Reset I, leaving MS */
1306: UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
1307: }
1308: else
1309: {
1310: zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1311: inet_ntoa(nbr->router_id));
1312: break;
1313: }
1314:
1315: /* This is where the real Options are saved */
1316: nbr->options = dd->options;
1317:
1318: if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
1319: {
1320: if (IS_DEBUG_OSPF_EVENT)
1321: zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
1322: inet_ntoa (nbr->router_id),
1323: CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1324:
1325: if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1326: && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1327: {
1328: zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1329: "Opaque-LSAs cannot be reliably advertised "
1330: "in this network.",
1331: inet_ntoa (nbr->router_id));
1332: /* This situation is undesirable, but not a real error. */
1333: }
1334: }
1335:
1336: OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1337:
1338: /* continue processing rest of packet. */
1339: ospf_db_desc_proc (s, oi, nbr, dd, size);
1340: break;
1341: case NSM_Exchange:
1342: if (ospf_db_desc_is_dup (dd, nbr))
1343: {
1344: if (IS_SET_DD_MS (nbr->dd_flags))
1345: /* Master: discard duplicated DD packet. */
1346: zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1347: inet_ntoa (nbr->router_id));
1348: else
1349: /* Slave: cause to retransmit the last Database Description. */
1350: {
1351: zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1352: inet_ntoa (nbr->router_id));
1353: ospf_db_desc_resend (nbr);
1354: }
1355: break;
1356: }
1357:
1358: /* Otherwise DD packet should be checked. */
1359: /* Check Master/Slave bit mismatch */
1360: if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1361: {
1362: zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1363: inet_ntoa(nbr->router_id));
1364: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1365: if (IS_DEBUG_OSPF_EVENT)
1366: zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1367: dd->flags, nbr->dd_flags);
1368: break;
1369: }
1370:
1371: /* Check initialize bit is set. */
1372: if (IS_SET_DD_I (dd->flags))
1373: {
1374: zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
1375: inet_ntoa(nbr->router_id));
1376: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1377: break;
1378: }
1379:
1380: /* Check DD Options. */
1381: if (dd->options != nbr->options)
1382: {
1383: #ifdef ORIGINAL_CODING
1384: /* Save the new options for debugging */
1385: nbr->options = dd->options;
1386: #endif /* ORIGINAL_CODING */
1387: zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1388: inet_ntoa(nbr->router_id));
1389: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1390: break;
1391: }
1392:
1393: /* Check DD sequence number. */
1394: if ((IS_SET_DD_MS (nbr->dd_flags) &&
1395: ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1396: (!IS_SET_DD_MS (nbr->dd_flags) &&
1397: ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1398: {
1399: zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1400: inet_ntoa(nbr->router_id));
1401: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1402: break;
1403: }
1404:
1405: /* Continue processing rest of packet. */
1406: ospf_db_desc_proc (s, oi, nbr, dd, size);
1407: break;
1408: case NSM_Loading:
1409: case NSM_Full:
1410: if (ospf_db_desc_is_dup (dd, nbr))
1411: {
1412: if (IS_SET_DD_MS (nbr->dd_flags))
1413: {
1414: /* Master should discard duplicate DD packet. */
1415: zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1416: "packet discarded.",
1417: inet_ntoa(nbr->router_id));
1418: break;
1419: }
1420: else
1421: {
1422: struct timeval t, now;
1423: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1424: t = tv_sub (now, nbr->last_send_ts);
1425: if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1426: {
1427: /* In states Loading and Full the slave must resend
1428: its last Database Description packet in response to
1429: duplicate Database Description packets received
1430: from the master. For this reason the slave must
1431: wait RouterDeadInterval seconds before freeing the
1432: last Database Description packet. Reception of a
1433: Database Description packet from the master after
1434: this interval will generate a SeqNumberMismatch
1435: neighbor event. RFC2328 Section 10.8 */
1436: ospf_db_desc_resend (nbr);
1437: break;
1438: }
1439: }
1440: }
1441:
1442: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1443: break;
1444: default:
1445: zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1446: inet_ntoa(nbr->router_id), nbr->state);
1447: break;
1448: }
1449: }
1450:
1451: #define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1452:
1453: /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1454: static void
1455: ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1456: struct stream *s, struct ospf_interface *oi, u_int16_t size)
1457: {
1458: struct ospf_neighbor *nbr;
1459: u_int32_t ls_type;
1460: struct in_addr ls_id;
1461: struct in_addr adv_router;
1462: struct ospf_lsa *find;
1463: struct list *ls_upd;
1464: unsigned int length;
1465:
1466: /* Increment statistics. */
1467: oi->ls_req_in++;
1468:
1469: nbr = ospf_nbr_lookup (oi, iph, ospfh);
1470: if (nbr == NULL)
1471: {
1472: zlog_warn ("Link State Request: Unknown Neighbor %s.",
1473: inet_ntoa (ospfh->router_id));
1474: return;
1475: }
1476:
1477: /* Add event to thread. */
1478: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1479:
1480: /* Neighbor State should be Exchange or later. */
1481: if (nbr->state != NSM_Exchange &&
1482: nbr->state != NSM_Loading &&
1483: nbr->state != NSM_Full)
1484: {
1485: zlog_warn ("Link State Request received from %s: "
1486: "Neighbor state is %s, packet discarded.",
1487: inet_ntoa (ospfh->router_id),
1488: LOOKUP (ospf_nsm_state_msg, nbr->state));
1489: return;
1490: }
1491:
1492: /* Send Link State Update for ALL requested LSAs. */
1493: ls_upd = list_new ();
1494: length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1495:
1496: while (size >= OSPF_LSA_KEY_SIZE)
1497: {
1498: /* Get one slice of Link State Request. */
1499: ls_type = stream_getl (s);
1500: ls_id.s_addr = stream_get_ipv4 (s);
1501: adv_router.s_addr = stream_get_ipv4 (s);
1502:
1503: /* Verify LSA type. */
1504: if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1505: {
1506: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1507: list_delete (ls_upd);
1508: return;
1509: }
1510:
1511: /* Search proper LSA in LSDB. */
1512: find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1513: if (find == NULL)
1514: {
1515: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1516: list_delete (ls_upd);
1517: return;
1518: }
1519:
1520: /* Packet overflows MTU size, send immediately. */
1521: if (length + ntohs (find->data->length) > ospf_packet_max (oi))
1522: {
1523: if (oi->type == OSPF_IFTYPE_NBMA)
1524: ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1525: else
1526: ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1527:
1528: /* Only remove list contents. Keep ls_upd. */
1529: list_delete_all_node (ls_upd);
1530:
1531: length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1532: }
1533:
1534: /* Append LSA to update list. */
1535: listnode_add (ls_upd, find);
1536: length += ntohs (find->data->length);
1537:
1538: size -= OSPF_LSA_KEY_SIZE;
1539: }
1540:
1541: /* Send rest of Link State Update. */
1542: if (listcount (ls_upd) > 0)
1543: {
1544: if (oi->type == OSPF_IFTYPE_NBMA)
1545: ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1546: else
1547: ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1548:
1549: list_delete (ls_upd);
1550: }
1551: else
1552: list_free (ls_upd);
1553: }
1554:
1555: /* Get the list of LSAs from Link State Update packet.
1556: And process some validation -- RFC2328 Section 13. (1)-(2). */
1557: static struct list *
1558: ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1559: struct ospf_interface *oi, size_t size)
1560: {
1561: u_int16_t count, sum;
1562: u_int32_t length;
1563: struct lsa_header *lsah;
1564: struct ospf_lsa *lsa;
1565: struct list *lsas;
1566:
1567: lsas = list_new ();
1568:
1569: count = stream_getl (s);
1570: size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1571:
1572: for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1573: size -= length, stream_forward_getp (s, length), count--)
1574: {
1575: lsah = (struct lsa_header *) STREAM_PNT (s);
1576: length = ntohs (lsah->length);
1577:
1578: if (length > size)
1579: {
1580: zlog_warn ("Link State Update: LSA length exceeds packet size.");
1581: break;
1582: }
1583:
1584: /* Validate the LSA's LS checksum. */
1585: sum = lsah->checksum;
1.1.1.4 misho 1586: if (! ospf_lsa_checksum_valid (lsah))
1.1 misho 1587: {
1.1.1.3 misho 1588: /* (bug #685) more details in a one-line message make it possible
1589: * to identify problem source on the one hand and to have a better
1590: * chance to compress repeated messages in syslog on the other */
1591: zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1592: sum, lsah->checksum, inet_ntoa (lsah->id),
1593: inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1594: inet_ntoa (lsah->adv_router));
1.1 misho 1595: continue;
1596: }
1597:
1598: /* Examine the LSA's LS type. */
1599: if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1600: {
1601: zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1602: continue;
1603: }
1604:
1605: /*
1606: * What if the received LSA's age is greater than MaxAge?
1607: * Treat it as a MaxAge case -- endo.
1608: */
1609: if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1610: lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1611:
1612: if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1613: {
1614: #ifdef STRICT_OBIT_USAGE_CHECK
1615: if ((IS_OPAQUE_LSA(lsah->type) &&
1616: ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1617: || (! IS_OPAQUE_LSA(lsah->type) &&
1618: CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1619: {
1620: /*
1621: * This neighbor must know the exact usage of O-bit;
1622: * the bit will be set in Type-9,10,11 LSAs only.
1623: */
1624: zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1625: continue;
1626: }
1627: #endif /* STRICT_OBIT_USAGE_CHECK */
1628:
1629: /* Do not take in AS External Opaque-LSAs if we are a stub. */
1630: if (lsah->type == OSPF_OPAQUE_AS_LSA
1631: && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1632: {
1633: if (IS_DEBUG_OSPF_EVENT)
1634: zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1635: continue;
1636: }
1637: }
1638: else if (IS_OPAQUE_LSA(lsah->type))
1639: {
1640: zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1641: continue;
1642: }
1643:
1644: /* Create OSPF LSA instance. */
1645: lsa = ospf_lsa_new ();
1646:
1647: /* We may wish to put some error checking if type NSSA comes in
1648: and area not in NSSA mode */
1649: switch (lsah->type)
1650: {
1651: case OSPF_AS_EXTERNAL_LSA:
1652: case OSPF_OPAQUE_AS_LSA:
1653: lsa->area = NULL;
1654: break;
1655: case OSPF_OPAQUE_LINK_LSA:
1656: lsa->oi = oi; /* Remember incoming interface for flooding control. */
1657: /* Fallthrough */
1658: default:
1659: lsa->area = oi->area;
1660: break;
1661: }
1662:
1663: lsa->data = ospf_lsa_data_new (length);
1664: memcpy (lsa->data, lsah, length);
1665:
1666: if (IS_DEBUG_OSPF_EVENT)
1667: zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1.1.1.5 ! misho 1668: lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
1.1 misho 1669: listnode_add (lsas, lsa);
1670: }
1671:
1672: return lsas;
1673: }
1674:
1675: /* Cleanup Update list. */
1676: static void
1677: ospf_upd_list_clean (struct list *lsas)
1678: {
1679: struct listnode *node, *nnode;
1680: struct ospf_lsa *lsa;
1681:
1682: for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1683: ospf_lsa_discard (lsa);
1684:
1685: list_delete (lsas);
1686: }
1687:
1688: /* OSPF Link State Update message read -- RFC2328 Section 13. */
1689: static void
1.1.1.5 ! misho 1690: ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh,
1.1 misho 1691: struct stream *s, struct ospf_interface *oi, u_int16_t size)
1692: {
1693: struct ospf_neighbor *nbr;
1694: struct list *lsas;
1695: struct listnode *node, *nnode;
1696: struct ospf_lsa *lsa = NULL;
1697: /* unsigned long ls_req_found = 0; */
1698:
1699: /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1700:
1701: /* Increment statistics. */
1702: oi->ls_upd_in++;
1703:
1704: /* Check neighbor. */
1705: nbr = ospf_nbr_lookup (oi, iph, ospfh);
1706: if (nbr == NULL)
1707: {
1708: zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1709: inet_ntoa (ospfh->router_id), IF_NAME (oi));
1710: return;
1711: }
1712:
1713: /* Add event to thread. */
1714: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
1715:
1716: /* Check neighbor state. */
1717: if (nbr->state < NSM_Exchange)
1718: {
1719: zlog_warn ("Link State Update: "
1720: "Neighbor[%s] state %s is less than Exchange",
1721: inet_ntoa (ospfh->router_id),
1722: LOOKUP(ospf_nsm_state_msg, nbr->state));
1723: return;
1724: }
1725:
1726: /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1727: * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1728: * of section 13.
1729: */
1730: lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1731:
1732: #define DISCARD_LSA(L,N) {\
1733: if (IS_DEBUG_OSPF_EVENT) \
1.1.1.5 ! misho 1734: zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \
! 1735: " Type-%d", N, (void *)lsa, (int) lsa->data->type); \
1.1 misho 1736: ospf_lsa_discard (L); \
1737: continue; }
1738:
1.1.1.4 misho 1739: /* Process each LSA received in the one packet.
1740: *
1741: * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
1742: * text below are from the steps in RFC 2328, Section 13.
1743: */
1.1 misho 1744: for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1745: {
1746: struct ospf_lsa *ls_ret, *current;
1747: int ret = 1;
1748:
1749: if (IS_DEBUG_OSPF_NSSA)
1750: {
1751: char buf1[INET_ADDRSTRLEN];
1752: char buf2[INET_ADDRSTRLEN];
1753: char buf3[INET_ADDRSTRLEN];
1754:
1755: zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
1756: 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: }
1764:
1765: listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1766:
1.1.1.4 misho 1767: /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1.1 misho 1768:
1.1.1.4 misho 1769: /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
1.1 misho 1770:
1.1.1.4 misho 1771: /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
1.1 misho 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: {
1786: if (IS_DEBUG_OSPF_NSSA)
1787: zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
1788: DISCARD_LSA (lsa, 1);
1789: }
1790:
1791: if (lsa->data->type == OSPF_AS_NSSA_LSA)
1792: if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1793: {
1794: if (IS_DEBUG_OSPF_NSSA)
1795: zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
1796: DISCARD_LSA (lsa,2);
1797: }
1798:
1.1.1.5 ! misho 1799: /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
! 1800: if (lsa->data->type == OSPF_ROUTER_LSA)
! 1801: if (!IPV4_ADDR_SAME(&lsa->data->id, &lsa->data->adv_router))
! 1802: {
! 1803: char buf1[INET_ADDRSTRLEN];
! 1804: char buf2[INET_ADDRSTRLEN];
! 1805: char buf3[INET_ADDRSTRLEN];
! 1806:
! 1807: zlog_err("Incoming Router-LSA from %s with "
! 1808: "Adv-ID[%s] != LS-ID[%s]",
! 1809: inet_ntop (AF_INET, &ospfh->router_id,
! 1810: buf1, INET_ADDRSTRLEN),
! 1811: inet_ntop (AF_INET, &lsa->data->id,
! 1812: buf2, INET_ADDRSTRLEN),
! 1813: inet_ntop (AF_INET, &lsa->data->adv_router,
! 1814: buf3, INET_ADDRSTRLEN));
! 1815: zlog_err("OSPF domain compromised by attack or corruption. "
! 1816: "Verify correct operation of -ALL- OSPF routers.");
! 1817: DISCARD_LSA (lsa, 0);
! 1818: }
! 1819:
1.1 misho 1820: /* Find the LSA in the current database. */
1821:
1822: current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1823:
1.1.1.4 misho 1824: /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
1.1 misho 1825: no instance of the LSA in the router's link state database,
1826: and none of router's neighbors are in states Exchange or Loading,
1.1.1.4 misho 1827: then take the following actions: */
1.1 misho 1828:
1829: if (IS_LSA_MAXAGE (lsa) && !current &&
1.1.1.5 ! misho 1830: ospf_check_nbr_status(oi->ospf))
1.1 misho 1831: {
1.1.1.4 misho 1832: /* (4a) Response Link State Acknowledgment. */
1.1 misho 1833: ospf_ls_ack_send (nbr, lsa);
1834:
1.1.1.4 misho 1835: /* (4b) Discard LSA. */
1836: if (IS_DEBUG_OSPF (lsa, LSA))
1837: {
1838: zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
1839: dump_lsa_key(lsa));
1840: }
1.1 misho 1841: DISCARD_LSA (lsa, 3);
1842: }
1843:
1844: if (IS_OPAQUE_LSA (lsa->data->type)
1845: && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
1846: {
1847: /*
1848: * Even if initial flushing seems to be completed, there might
1849: * be a case that self-originated LSA with MaxAge still remain
1850: * in the routing domain.
1851: * Just send an LSAck message to cease retransmission.
1852: */
1853: if (IS_LSA_MAXAGE (lsa))
1854: {
1855: zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1856: ospf_ls_ack_send (nbr, lsa);
1857: ospf_lsa_discard (lsa);
1858:
1859: if (current != NULL && ! IS_LSA_MAXAGE (current))
1860: ospf_opaque_lsa_refresh_schedule (current);
1861: continue;
1862: }
1863:
1864: /*
1865: * If an instance of self-originated Opaque-LSA is not found
1866: * in the LSDB, there are some possible cases here.
1867: *
1868: * 1) This node lost opaque-capability after restart.
1869: * 2) Else, a part of opaque-type is no more supported.
1870: * 3) Else, a part of opaque-id is no more supported.
1871: *
1872: * Anyway, it is still this node's responsibility to flush it.
1873: * Otherwise, the LSA instance remains in the routing domain
1874: * until its age reaches to MaxAge.
1875: */
1876: /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
1877: if (current == NULL)
1878: {
1879: if (IS_DEBUG_OSPF_EVENT)
1880: zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1881: "not found in the LSDB.", dump_lsa_key (lsa));
1882:
1883: SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1884:
1885: ospf_opaque_self_originated_lsa_received (nbr, lsa);
1886: ospf_ls_ack_send (nbr, lsa);
1887:
1888: continue;
1889: }
1890: }
1891:
1892: /* It might be happen that received LSA is self-originated network LSA, but
1.1.1.4 misho 1893: * router ID is changed. So, we should check if LSA is a network-LSA whose
1.1 misho 1894: * Link State ID is one of the router's own IP interface addresses but whose
1895: * Advertising Router is not equal to the router's own Router ID
1896: * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1897: */
1898:
1899: if(lsa->data->type == OSPF_NETWORK_LSA)
1900: {
1901: struct listnode *oinode, *oinnode;
1902: struct ospf_interface *out_if;
1903: int Flag = 0;
1904:
1905: for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
1906: {
1907: if(out_if == NULL)
1908: break;
1909:
1910: if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1911: (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1912: {
1913: if(out_if->network_lsa_self)
1914: {
1915: ospf_lsa_flush_area(lsa,out_if->area);
1916: if(IS_DEBUG_OSPF_EVENT)
1917: zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
1.1.1.5 ! misho 1918: (void *)lsa, (int) lsa->data->type);
1.1 misho 1919: ospf_lsa_discard (lsa);
1920: Flag = 1;
1921: }
1922: break;
1923: }
1924: }
1925: if(Flag)
1926: continue;
1927: }
1928:
1929: /* (5) Find the instance of this LSA that is currently contained
1930: in the router's link state database. If there is no
1931: database copy, or the received LSA is more recent than
1.1.1.4 misho 1932: the database copy the following steps must be performed.
1933: (The sub steps from RFC 2328 section 13 step (5) will be performed in
1934: ospf_flood() ) */
1.1 misho 1935:
1936: if (current == NULL ||
1937: (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1938: {
1939: /* Actual flooding procedure. */
1940: if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
1941: DISCARD_LSA (lsa, 4);
1942: continue;
1943: }
1944:
1945: /* (6) Else, If there is an instance of the LSA on the sending
1946: neighbor's Link state request list, an error has occurred in
1947: the Database Exchange process. In this case, restart the
1948: Database Exchange process by generating the neighbor event
1949: BadLSReq for the sending neighbor and stop processing the
1950: Link State Update packet. */
1951:
1952: if (ospf_ls_request_lookup (nbr, lsa))
1953: {
1954: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1955: zlog_warn("LSA[%s] instance exists on Link state request list",
1956: dump_lsa_key(lsa));
1957:
1958: /* Clean list of LSAs. */
1959: ospf_upd_list_clean (lsas);
1960: /* this lsa is not on lsas list already. */
1961: ospf_lsa_discard (lsa);
1962: return;
1963: }
1964:
1965: /* If the received LSA is the same instance as the database copy
1966: (i.e., neither one is more recent) the following two steps
1967: should be performed: */
1968:
1969: if (ret == 0)
1970: {
1971: /* If the LSA is listed in the Link state retransmission list
1972: for the receiving adjacency, the router itself is expecting
1973: an acknowledgment for this LSA. The router should treat the
1974: received LSA as an acknowledgment by removing the LSA from
1975: the Link state retransmission list. This is termed an
1976: "implied acknowledgment". */
1977:
1978: ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1979:
1980: if (ls_ret != NULL)
1981: {
1982: ospf_ls_retransmit_delete (nbr, ls_ret);
1983:
1984: /* Delayed acknowledgment sent if advertisement received
1985: from Designated Router, otherwise do nothing. */
1986: if (oi->state == ISM_Backup)
1987: if (NBR_IS_DR (nbr))
1988: listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1989:
1990: DISCARD_LSA (lsa, 5);
1991: }
1992: else
1993: /* Acknowledge the receipt of the LSA by sending a
1994: Link State Acknowledgment packet back out the receiving
1995: interface. */
1996: {
1997: ospf_ls_ack_send (nbr, lsa);
1998: DISCARD_LSA (lsa, 6);
1999: }
2000: }
2001:
2002: /* The database copy is more recent. If the database copy
2003: has LS age equal to MaxAge and LS sequence number equal to
2004: MaxSequenceNumber, simply discard the received LSA without
2005: acknowledging it. (In this case, the LSA's LS sequence number is
2006: wrapping, and the MaxSequenceNumber LSA must be completely
2007: flushed before any new LSA instance can be introduced). */
2008:
2009: else if (ret > 0) /* Database copy is more recent */
2010: {
2011: if (IS_LSA_MAXAGE (current) &&
2012: current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2013: {
2014: DISCARD_LSA (lsa, 7);
2015: }
2016: /* Otherwise, as long as the database copy has not been sent in a
2017: Link State Update within the last MinLSArrival seconds, send the
2018: database copy back to the sending neighbor, encapsulated within
2019: a Link State Update Packet. The Link State Update Packet should
2020: be sent directly to the neighbor. In so doing, do not put the
2021: database copy of the LSA on the neighbor's link state
2022: retransmission list, and do not acknowledge the received (less
2023: recent) LSA instance. */
2024: else
2025: {
2026: struct timeval now;
2027:
2028: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
2029:
2030: if (tv_cmp (tv_sub (now, current->tv_orig),
1.1.1.5 ! misho 2031: msec2tv (ospf->min_ls_arrival)) >= 0)
1.1 misho 2032: /* Trap NSSA type later.*/
2033: ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2034: DISCARD_LSA (lsa, 8);
2035: }
2036: }
2037: }
2038: #undef DISCARD_LSA
2039:
2040: assert (listcount (lsas) == 0);
2041: list_delete (lsas);
2042: }
2043:
2044: /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
2045: static void
2046: ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2047: struct stream *s, struct ospf_interface *oi, u_int16_t size)
2048: {
2049: struct ospf_neighbor *nbr;
2050:
2051: /* increment statistics. */
2052: oi->ls_ack_in++;
2053:
2054: nbr = ospf_nbr_lookup (oi, iph, ospfh);
2055: if (nbr == NULL)
2056: {
2057: zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2058: inet_ntoa (ospfh->router_id));
2059: return;
2060: }
2061:
2062: /* Add event to thread. */
2063: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2064:
2065: if (nbr->state < NSM_Exchange)
2066: {
2067: zlog_warn ("Link State Acknowledgment: "
2068: "Neighbor[%s] state %s is less than Exchange",
2069: inet_ntoa (ospfh->router_id),
2070: LOOKUP(ospf_nsm_state_msg, nbr->state));
2071: return;
2072: }
2073:
2074: while (size >= OSPF_LSA_HEADER_SIZE)
2075: {
2076: struct ospf_lsa *lsa, *lsr;
2077:
2078: lsa = ospf_lsa_new ();
2079: lsa->data = (struct lsa_header *) STREAM_PNT (s);
2080:
2081: /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2082: size -= OSPF_LSA_HEADER_SIZE;
2083: stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
2084:
2085: if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2086: {
2087: lsa->data = NULL;
2088: ospf_lsa_discard (lsa);
2089: continue;
2090: }
2091:
2092: lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2093:
1.1.1.5 ! misho 2094: if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0)
! 2095: ospf_ls_retransmit_delete (nbr, lsr);
1.1 misho 2096:
2097: lsa->data = NULL;
2098: ospf_lsa_discard (lsa);
2099: }
2100:
2101: return;
2102: }
1.1.1.5 ! misho 2103:
1.1 misho 2104: static struct stream *
2105: ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
2106: {
2107: int ret;
2108: struct ip *iph;
2109: u_int16_t ip_len;
1.1.1.5 ! misho 2110: ifindex_t ifindex = 0;
1.1 misho 2111: struct iovec iov;
2112: /* Header and data both require alignment. */
2113: char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2114: struct msghdr msgh;
2115:
2116: memset (&msgh, 0, sizeof (struct msghdr));
2117: msgh.msg_iov = &iov;
2118: msgh.msg_iovlen = 1;
2119: msgh.msg_control = (caddr_t) buff;
2120: msgh.msg_controllen = sizeof (buff);
2121:
2122: ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2123: if (ret < 0)
2124: {
2125: zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2126: return NULL;
2127: }
2128: if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
2129: {
2130: zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2131: "(ip header size is %u)",
2132: ret, (u_int)sizeof(iph));
2133: return NULL;
2134: }
2135:
2136: /* Note that there should not be alignment problems with this assignment
2137: because this is at the beginning of the stream data buffer. */
2138: iph = (struct ip *) STREAM_DATA(ibuf);
2139: sockopt_iphdrincl_swab_systoh (iph);
2140:
2141: ip_len = iph->ip_len;
2142:
1.1.1.3 misho 2143: #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
1.1 misho 2144: /*
2145: * Kernel network code touches incoming IP header parameters,
2146: * before protocol specific processing.
2147: *
2148: * 1) Convert byteorder to host representation.
2149: * --> ip_len, ip_id, ip_off
2150: *
2151: * 2) Adjust ip_len to strip IP header size!
2152: * --> If user process receives entire IP packet via RAW
2153: * socket, it must consider adding IP header size to
2154: * the "ip_len" field of "ip" structure.
2155: *
2156: * For more details, see <netinet/ip_input.c>.
2157: */
2158: ip_len = ip_len + (iph->ip_hl << 2);
2159: #endif
2160:
2161: #if defined(__DragonFly__)
2162: /*
2163: * in DragonFly's raw socket, ip_len/ip_off are read
2164: * in network byte order.
2165: * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2166: */
2167: ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2168: #endif
2169:
2170: ifindex = getsockopt_ifindex (AF_INET, &msgh);
2171:
2172: *ifp = if_lookup_by_index (ifindex);
2173:
2174: if (ret != ip_len)
2175: {
2176: zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2177: "but recvmsg returned %d", ip_len, ret);
2178: return NULL;
2179: }
2180:
2181: return ibuf;
2182: }
2183:
2184: static struct ospf_interface *
2185: ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
2186: struct ip *iph, struct ospf_header *ospfh)
2187: {
2188: struct ospf_interface *rcv_oi;
2189: struct ospf_vl_data *vl_data;
2190: struct ospf_area *vl_area;
2191: struct listnode *node;
2192:
2193: if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2194: !OSPF_IS_AREA_BACKBONE (ospfh))
2195: return NULL;
2196:
2197: /* look for local OSPF interface matching the destination
2198: * to determine Area ID. We presume therefore the destination address
2199: * is unique, or at least (for "unnumbered" links), not used in other
2200: * areas
2201: */
2202: if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2203: iph->ip_dst)) == NULL)
2204: return NULL;
2205:
2206: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
2207: {
2208: vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
2209: if (!vl_area)
2210: continue;
2211:
2212: if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2213: IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2214: {
2215: if (IS_DEBUG_OSPF_EVENT)
2216: zlog_debug ("associating packet with %s",
2217: IF_NAME (vl_data->vl_oi));
2218: if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2219: {
2220: if (IS_DEBUG_OSPF_EVENT)
2221: zlog_debug ("This VL is not up yet, sorry");
2222: return NULL;
2223: }
2224:
2225: return vl_data->vl_oi;
2226: }
2227: }
2228:
2229: if (IS_DEBUG_OSPF_EVENT)
2230: zlog_debug ("couldn't find any VL to associate the packet with");
2231:
2232: return NULL;
2233: }
2234:
1.1.1.3 misho 2235: static int
1.1 misho 2236: ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2237: {
2238: /* Check match the Area ID of the receiving interface. */
2239: if (OSPF_AREA_SAME (&oi->area, &ospfh))
2240: return 1;
2241:
2242: return 0;
2243: }
2244:
2245: /* Unbound socket will accept any Raw IP packets if proto is matched.
2246: To prevent it, compare src IP address and i/f address with masking
2247: i/f network mask. */
2248: static int
2249: ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2250: {
2251: struct in_addr mask, me, him;
2252:
2253: if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2254: oi->type == OSPF_IFTYPE_VIRTUALLINK)
2255: return 1;
2256:
2257: masklen2ip (oi->address->prefixlen, &mask);
2258:
2259: me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2260: him.s_addr = ip_src.s_addr & mask.s_addr;
2261:
2262: if (IPV4_ADDR_SAME (&me, &him))
2263: return 1;
2264:
2265: return 0;
2266: }
2267:
1.1.1.2 misho 2268: /* Return 1, if the packet is properly authenticated and checksummed,
2269: 0 otherwise. In particular, check that AuType header field is valid and
2270: matches the locally configured AuType, and that D.5 requirements are met. */
1.1 misho 2271: static int
1.1.1.2 misho 2272: ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
1.1 misho 2273: {
2274: struct crypt_key *ck;
1.1.1.2 misho 2275: u_int16_t iface_auth_type;
2276: u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
1.1 misho 2277:
1.1.1.2 misho 2278: switch (pkt_auth_type)
2279: {
2280: case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2281: if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
1.1 misho 2282: {
1.1.1.2 misho 2283: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2284: zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2285: IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2286: return 0;
1.1 misho 2287: }
1.1.1.2 misho 2288: if (! ospf_check_sum (ospfh))
2289: {
2290: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2291: zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2292: IF_NAME (oi), inet_ntoa (ospfh->router_id));
2293: return 0;
2294: }
2295: return 1;
2296: case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2297: if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2298: {
2299: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2300: zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2301: IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2302: return 0;
2303: }
2304: if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2305: {
2306: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2307: zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2308: return 0;
2309: }
2310: if (! ospf_check_sum (ospfh))
2311: {
2312: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2313: zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2314: IF_NAME (oi), inet_ntoa (ospfh->router_id));
2315: return 0;
2316: }
2317: return 1;
2318: case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2319: if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2320: {
2321: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2322: zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2323: IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2324: return 0;
2325: }
2326: if (ospfh->checksum)
2327: {
2328: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2329: zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2330: return 0;
2331: }
2332: /* only MD5 crypto method can pass ospf_packet_examin() */
2333: if
2334: (
2335: NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2336: ospfh->u.crypt.key_id != ck->key_id ||
2337: /* Condition above uses the last key ID on the list, which is
2338: different from what ospf_crypt_key_lookup() does. A bug? */
2339: ! ospf_check_md5_digest (oi, ospfh)
2340: )
2341: {
2342: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2343: zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2344: return 0;
2345: }
2346: return 1;
2347: default:
2348: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2349: zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2350: IF_NAME (oi), pkt_auth_type);
2351: return 0;
2352: }
1.1 misho 2353: }
2354:
2355: static int
2356: ospf_check_sum (struct ospf_header *ospfh)
2357: {
2358: u_int32_t ret;
2359: u_int16_t sum;
2360:
2361: /* clear auth_data for checksum. */
2362: memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2363:
2364: /* keep checksum and clear. */
2365: sum = ospfh->checksum;
2366: memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2367:
2368: /* calculate checksum. */
2369: ret = in_cksum (ospfh, ntohs (ospfh->length));
2370:
2371: if (ret != sum)
2372: {
2373: zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2374: ret, sum);
2375: return 0;
2376: }
2377:
2378: return 1;
2379: }
2380:
1.1.1.2 misho 2381: /* Verify, that given link/TOS records are properly sized/aligned and match
2382: Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2383: static unsigned
2384: ospf_router_lsa_links_examin
2385: (
2386: struct router_lsa_link * link,
2387: u_int16_t linkbytes,
2388: const u_int16_t num_links
2389: )
1.1 misho 2390: {
1.1.1.2 misho 2391: unsigned counted_links = 0, thislinklen;
2392:
2393: while (linkbytes)
2394: {
2395: thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2396: if (thislinklen > linkbytes)
1.1 misho 2397: {
1.1.1.2 misho 2398: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2399: zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2400: return MSG_NG;
1.1 misho 2401: }
1.1.1.2 misho 2402: link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2403: linkbytes -= thislinklen;
2404: counted_links++;
2405: }
2406: if (counted_links != num_links)
2407: {
2408: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2409: zlog_debug ("%s: %u link blocks declared, %u present",
2410: __func__, num_links, counted_links);
2411: return MSG_NG;
2412: }
2413: return MSG_OK;
2414: }
1.1 misho 2415:
1.1.1.2 misho 2416: /* Verify, that the given LSA is properly sized/aligned (including type-specific
2417: minimum length constraint). */
2418: static unsigned
2419: ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2420: {
2421: unsigned ret;
2422: struct router_lsa * rlsa;
2423: if
2424: (
2425: lsah->type < OSPF_MAX_LSA &&
2426: ospf_lsa_minlen[lsah->type] &&
2427: lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2428: )
1.1 misho 2429: {
1.1.1.2 misho 2430: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2431: zlog_debug ("%s: undersized (%u B) %s",
2432: __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2433: return MSG_NG;
2434: }
2435: switch (lsah->type)
2436: {
2437: case OSPF_ROUTER_LSA:
2438: /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2439: if (headeronly)
2440: {
2441: ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2442: break;
2443: }
2444: rlsa = (struct router_lsa *) lsah;
2445: ret = ospf_router_lsa_links_examin
2446: (
2447: (struct router_lsa_link *) rlsa->link,
2448: lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2449: ntohs (rlsa->links) /* 16 bits */
2450: );
2451: break;
2452: case OSPF_AS_EXTERNAL_LSA:
2453: /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2454: case OSPF_AS_NSSA_LSA:
2455: /* RFC3101 C, idem */
2456: ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2457: break;
2458: /* Following LSA types are considered OK length-wise as soon as their minimum
2459: * length constraint is met and length of the whole LSA is a multiple of 4
2460: * (basic LSA header size is already a multiple of 4). */
2461: case OSPF_NETWORK_LSA:
2462: /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2463: case OSPF_SUMMARY_LSA:
2464: case OSPF_ASBR_SUMMARY_LSA:
2465: /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2466: case OSPF_OPAQUE_LINK_LSA:
2467: case OSPF_OPAQUE_AREA_LSA:
2468: case OSPF_OPAQUE_AS_LSA:
2469: /* RFC5250 A.2, "some number of octets (of application-specific
2470: * data) padded to 32-bit alignment." This is considered equivalent
2471: * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2472: * file for the detailed analysis of this passage. */
2473: ret = lsalen % 4 ? MSG_NG : MSG_OK;
2474: break;
2475: default:
2476: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2477: zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2478: return MSG_NG;
2479: }
2480: if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2481: zlog_debug ("%s: alignment error in %s",
2482: __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2483: return ret;
2484: }
2485:
2486: /* Verify if the provided input buffer is a valid sequence of LSAs. This
2487: includes verification of LSA blocks length/alignment and dispatching
2488: of deeper-level checks. */
2489: static unsigned
2490: ospf_lsaseq_examin
2491: (
2492: struct lsa_header *lsah, /* start of buffered data */
2493: size_t length,
2494: const u_char headeronly,
2495: /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2496: and treat the difference as an error. */
2497: const u_int32_t declared_num_lsas
2498: )
2499: {
2500: u_int32_t counted_lsas = 0;
2501:
2502: while (length)
2503: {
2504: u_int16_t lsalen;
2505: if (length < OSPF_LSA_HEADER_SIZE)
2506: {
2507: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2508: zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2509: __func__, length, counted_lsas);
2510: return MSG_NG;
2511: }
2512: /* save on ntohs() calls here and in the LSA validator */
2513: lsalen = ntohs (lsah->length);
2514: if (lsalen < OSPF_LSA_HEADER_SIZE)
2515: {
2516: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2517: zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2518: __func__, counted_lsas, lsalen);
2519: return MSG_NG;
2520: }
2521: if (headeronly)
2522: {
2523: /* less checks here and in ospf_lsa_examin() */
2524: if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2525: {
2526: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2527: zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2528: return MSG_NG;
2529: }
2530: lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2531: length -= OSPF_LSA_HEADER_SIZE;
2532: }
2533: else
2534: {
2535: /* make sure the input buffer is deep enough before further checks */
2536: if (lsalen > length)
2537: {
2538: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2539: zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2540: __func__, counted_lsas, lsalen, length);
2541: return MSG_NG;
2542: }
2543: if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2544: {
2545: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2546: zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2547: return MSG_NG;
2548: }
2549: lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2550: length -= lsalen;
2551: }
2552: counted_lsas++;
2553: }
2554:
2555: if (declared_num_lsas && counted_lsas != declared_num_lsas)
2556: {
2557: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2558: zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2559: __func__, declared_num_lsas, counted_lsas);
2560: return MSG_NG;
2561: }
2562: return MSG_OK;
2563: }
2564:
2565: /* Verify a complete OSPF packet for proper sizing/alignment. */
2566: static unsigned
2567: ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2568: {
2569: u_int16_t bytesdeclared, bytesauth;
2570: unsigned ret;
2571: struct ospf_ls_update * lsupd;
2572:
2573: /* Length, 1st approximation. */
2574: if (bytesonwire < OSPF_HEADER_SIZE)
2575: {
2576: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2577: zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2578: return MSG_NG;
2579: }
2580: /* Now it is safe to access header fields. Performing length check, allow
2581: * for possible extra bytes of crypto auth/padding, which are not counted
2582: * in the OSPF header "length" field. */
2583: if (oh->version != OSPF_VERSION)
2584: {
2585: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2586: zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2587: return MSG_NG;
2588: }
2589: bytesdeclared = ntohs (oh->length);
2590: if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2591: bytesauth = 0;
2592: else
2593: {
2594: if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2595: {
2596: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2597: zlog_debug ("%s: unsupported crypto auth length (%u B)",
2598: __func__, oh->u.crypt.auth_data_len);
2599: return MSG_NG;
2600: }
2601: bytesauth = OSPF_AUTH_MD5_SIZE;
2602: }
2603: if (bytesdeclared + bytesauth > bytesonwire)
2604: {
2605: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2606: zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2607: __func__, bytesonwire, bytesdeclared, bytesauth);
2608: return MSG_NG;
2609: }
2610: /* Length, 2nd approximation. The type-specific constraint is checked
2611: against declared length, not amount of bytes on wire. */
2612: if
2613: (
2614: oh->type >= OSPF_MSG_HELLO &&
2615: oh->type <= OSPF_MSG_LS_ACK &&
2616: bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2617: )
2618: {
2619: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2620: zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2621: bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2622: return MSG_NG;
2623: }
2624: switch (oh->type)
2625: {
2626: case OSPF_MSG_HELLO:
2627: /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2628: by N>=0 router-IDs. */
2629: ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2630: break;
2631: case OSPF_MSG_DB_DESC:
2632: /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2633: by N>=0 header-only LSAs. */
2634: ret = ospf_lsaseq_examin
2635: (
2636: (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
2637: bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
2638: 1, /* header-only LSAs */
2639: 0
2640: );
2641: break;
2642: case OSPF_MSG_LS_REQ:
2643: /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
2644: ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
2645: OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2646: break;
2647: case OSPF_MSG_LS_UPD:
2648: /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2649: by N>=0 full LSAs (with N declared beforehand). */
2650: lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2651: ret = ospf_lsaseq_examin
2652: (
2653: (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
2654: bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
2655: 0, /* full LSAs */
2656: ntohl (lsupd->num_lsas) /* 32 bits */
2657: );
2658: break;
2659: case OSPF_MSG_LS_ACK:
2660: /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2661: ret = ospf_lsaseq_examin
2662: (
2663: (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
2664: bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
2665: 1, /* header-only LSAs */
2666: 0
2667: );
2668: break;
2669: default:
2670: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2671: zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2672: return MSG_NG;
1.1 misho 2673: }
1.1.1.2 misho 2674: if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2675: zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2676: return ret;
2677: }
1.1 misho 2678:
1.1.1.2 misho 2679: /* OSPF Header verification. */
2680: static int
2681: ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2682: struct ip *iph, struct ospf_header *ospfh)
2683: {
1.1 misho 2684: /* Check Area ID. */
2685: if (!ospf_check_area_id (oi, ospfh))
2686: {
2687: zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2688: IF_NAME (oi), inet_ntoa (ospfh->area_id));
2689: return -1;
2690: }
2691:
2692: /* Check network mask, Silently discarded. */
2693: if (! ospf_check_network_mask (oi, iph->ip_src))
2694: {
2695: zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2696: IF_NAME (oi), inet_ntoa (iph->ip_src));
2697: return -1;
2698: }
2699:
1.1.1.2 misho 2700: /* Check authentication. The function handles logging actions, where required. */
2701: if (! ospf_check_auth (oi, ospfh))
2702: return -1;
1.1 misho 2703:
2704: return 0;
2705: }
2706:
2707: /* Starting point of packet process function. */
2708: int
2709: ospf_read (struct thread *thread)
2710: {
2711: int ret;
2712: struct stream *ibuf;
2713: struct ospf *ospf;
2714: struct ospf_interface *oi;
2715: struct ip *iph;
2716: struct ospf_header *ospfh;
2717: u_int16_t length;
2718: struct interface *ifp;
2719:
2720: /* first of all get interface pointer. */
2721: ospf = THREAD_ARG (thread);
2722:
2723: /* prepare for next packet. */
2724: ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
2725:
2726: stream_reset(ospf->ibuf);
2727: if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
2728: return -1;
1.1.1.2 misho 2729: /* This raw packet is known to be at least as big as its IP header. */
1.1 misho 2730:
2731: /* Note that there should not be alignment problems with this assignment
2732: because this is at the beginning of the stream data buffer. */
2733: iph = (struct ip *) STREAM_DATA (ibuf);
2734: /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
2735:
2736: if (ifp == NULL)
2737: /* Handle cases where the platform does not support retrieving the ifindex,
2738: and also platforms (such as Solaris 8) that claim to support ifindex
2739: retrieval but do not. */
2740: ifp = if_lookup_address (iph->ip_src);
2741:
2742: if (ifp == NULL)
2743: return 0;
2744:
2745: /* IP Header dump. */
2746: if (IS_DEBUG_OSPF_PACKET(0, RECV))
2747: ospf_ip_header_dump (iph);
2748:
2749: /* Self-originated packet should be discarded silently. */
2750: if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
2751: {
2752: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2753: {
2754: zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
2755: inet_ntoa (iph->ip_src));
2756: }
2757: return 0;
2758: }
2759:
2760: /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2761: by ospf_recv_packet() to be correct). */
2762: stream_forward_getp (ibuf, iph->ip_hl * 4);
2763:
1.1.1.2 misho 2764: ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2765: if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
1.1 misho 2766: return -1;
2767: /* Now it is safe to access all fields of OSPF packet header. */
2768:
2769: /* associate packet with ospf interface */
2770: oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
2771:
2772: /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2773: after the passive/backbone/other checks below are passed. These checks
2774: in turn access the fields of unverified "ospfh" structure for their own
2775: purposes and must remain very accurate in doing this. */
2776:
2777: /* If incoming interface is passive one, ignore it. */
2778: if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2779: {
2780: char buf[3][INET_ADDRSTRLEN];
2781:
2782: if (IS_DEBUG_OSPF_EVENT)
2783: zlog_debug ("ignoring packet from router %s sent to %s, "
2784: "received on a passive interface, %s",
2785: inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2786: inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2787: inet_ntop(AF_INET, &oi->address->u.prefix4,
2788: buf[2], sizeof(buf[2])));
2789:
2790: if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2791: {
2792: /* Try to fix multicast membership.
2793: * Some OS:es may have problems in this area,
2794: * make sure it is removed.
2795: */
2796: OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2797: ospf_if_set_multicast(oi);
2798: }
2799: return 0;
2800: }
2801:
2802:
2803: /* if no local ospf_interface,
2804: * or header area is backbone but ospf_interface is not
2805: * check for VLINK interface
2806: */
2807: if ( (oi == NULL) ||
2808: (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2809: && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2810: )
2811: {
2812: if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2813: {
2814: if (IS_DEBUG_OSPF_EVENT)
2815: zlog_debug ("Packet from [%s] received on link %s"
2816: " but no ospf_interface",
2817: inet_ntoa (iph->ip_src), ifp->name);
2818: return 0;
2819: }
2820: }
2821:
2822: /* else it must be a local ospf interface, check it was received on
2823: * correct link
2824: */
2825: else if (oi->ifp != ifp)
2826: {
2827: if (IS_DEBUG_OSPF_EVENT)
2828: zlog_warn ("Packet from [%s] received on wrong link %s",
2829: inet_ntoa (iph->ip_src), ifp->name);
2830: return 0;
2831: }
2832: else if (oi->state == ISM_Down)
2833: {
2834: char buf[2][INET_ADDRSTRLEN];
2835: zlog_warn ("Ignoring packet from %s to %s received on interface that is "
2836: "down [%s]; interface flags are %s",
2837: inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2838: inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2839: ifp->name, if_flag_dump(ifp->flags));
2840: /* Fix multicast memberships? */
2841: if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2842: OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2843: else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2844: OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
2845: if (oi->multicast_memberships)
2846: ospf_if_set_multicast(oi);
2847: return 0;
2848: }
2849:
2850: /*
2851: * If the received packet is destined for AllDRouters, the packet
2852: * should be accepted only if the received ospf interface state is
2853: * either DR or Backup -- endo.
2854: */
2855: if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2856: && (oi->state != ISM_DR && oi->state != ISM_Backup))
2857: {
2858: zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2859: inet_ntoa (iph->ip_src), IF_NAME (oi),
2860: LOOKUP (ospf_ism_state_msg, oi->state));
2861: /* Try to fix multicast membership. */
2862: SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2863: ospf_if_set_multicast(oi);
2864: return 0;
2865: }
2866:
2867: /* Verify more OSPF header fields. */
2868: ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2869: if (ret < 0)
2870: {
2871: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2872: zlog_debug ("ospf_read[%s]: Header check failed, "
2873: "dropping.",
2874: inet_ntoa (iph->ip_src));
2875: return ret;
2876: }
2877:
2878: /* Show debug receiving packet. */
2879: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2880: {
2881: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2882: {
2883: zlog_debug ("-----------------------------------------------------");
2884: ospf_packet_dump (ibuf);
2885: }
2886:
2887: zlog_debug ("%s received from [%s] via [%s]",
1.1.1.2 misho 2888: LOOKUP (ospf_packet_type_str, ospfh->type),
1.1 misho 2889: inet_ntoa (ospfh->router_id), IF_NAME (oi));
2890: zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2891: zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
2892:
2893: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2894: zlog_debug ("-----------------------------------------------------");
2895: }
2896:
2897: stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
2898:
2899: /* Adjust size to message length. */
2900: length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2901:
2902: /* Read rest of the packet and call each sort of packet routine. */
2903: switch (ospfh->type)
2904: {
2905: case OSPF_MSG_HELLO:
2906: ospf_hello (iph, ospfh, ibuf, oi, length);
2907: break;
2908: case OSPF_MSG_DB_DESC:
2909: ospf_db_desc (iph, ospfh, ibuf, oi, length);
2910: break;
2911: case OSPF_MSG_LS_REQ:
2912: ospf_ls_req (iph, ospfh, ibuf, oi, length);
2913: break;
2914: case OSPF_MSG_LS_UPD:
1.1.1.5 ! misho 2915: ospf_ls_upd (ospf, iph, ospfh, ibuf, oi, length);
1.1 misho 2916: break;
2917: case OSPF_MSG_LS_ACK:
2918: ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2919: break;
2920: default:
2921: zlog (NULL, LOG_WARNING,
2922: "interface %s: OSPF packet header type %d is illegal",
2923: IF_NAME (oi), ospfh->type);
2924: break;
2925: }
2926:
2927: return 0;
2928: }
2929:
2930: /* Make OSPF header. */
2931: static void
2932: ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2933: {
2934: struct ospf_header *ospfh;
2935:
2936: ospfh = (struct ospf_header *) STREAM_DATA (s);
2937:
2938: ospfh->version = (u_char) OSPF_VERSION;
2939: ospfh->type = (u_char) type;
2940:
2941: ospfh->router_id = oi->ospf->router_id;
2942:
2943: ospfh->checksum = 0;
2944: ospfh->area_id = oi->area->area_id;
2945: ospfh->auth_type = htons (ospf_auth_type (oi));
2946:
2947: memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2948:
2949: stream_forward_endp (s, OSPF_HEADER_SIZE);
2950: }
2951:
2952: /* Make Authentication Data. */
2953: static int
2954: ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2955: {
2956: struct crypt_key *ck;
2957:
2958: switch (ospf_auth_type (oi))
2959: {
2960: case OSPF_AUTH_NULL:
2961: /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2962: break;
2963: case OSPF_AUTH_SIMPLE:
2964: memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2965: OSPF_AUTH_SIMPLE_SIZE);
2966: break;
2967: case OSPF_AUTH_CRYPTOGRAPHIC:
2968: /* If key is not set, then set 0. */
2969: if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2970: {
2971: ospfh->u.crypt.zero = 0;
2972: ospfh->u.crypt.key_id = 0;
2973: ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2974: }
2975: else
2976: {
2977: ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
2978: ospfh->u.crypt.zero = 0;
2979: ospfh->u.crypt.key_id = ck->key_id;
2980: ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2981: }
2982: /* note: the seq is done in ospf_make_md5_digest() */
2983: break;
2984: default:
2985: /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2986: break;
2987: }
2988:
2989: return 0;
2990: }
2991:
2992: /* Fill rest of OSPF header. */
2993: static void
2994: ospf_fill_header (struct ospf_interface *oi,
2995: struct stream *s, u_int16_t length)
2996: {
2997: struct ospf_header *ospfh;
2998:
2999: ospfh = (struct ospf_header *) STREAM_DATA (s);
3000:
3001: /* Fill length. */
3002: ospfh->length = htons (length);
3003:
3004: /* Calculate checksum. */
3005: if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3006: ospfh->checksum = in_cksum (ospfh, length);
3007: else
3008: ospfh->checksum = 0;
3009:
3010: /* Add Authentication Data. */
3011: ospf_make_auth (oi, ospfh);
3012: }
3013:
3014: static int
3015: ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3016: {
3017: struct ospf_neighbor *nbr;
3018: struct route_node *rn;
3019: u_int16_t length = OSPF_HELLO_MIN_SIZE;
3020: struct in_addr mask;
3021: unsigned long p;
3022: int flag = 0;
3023:
3024: /* Set netmask of interface. */
3025: if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3026: oi->type != OSPF_IFTYPE_VIRTUALLINK)
3027: masklen2ip (oi->address->prefixlen, &mask);
3028: else
3029: memset ((char *) &mask, 0, sizeof (struct in_addr));
3030: stream_put_ipv4 (s, mask.s_addr);
3031:
3032: /* Set Hello Interval. */
3033: if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3034: stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3035: else
3036: stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
3037:
3038: if (IS_DEBUG_OSPF_EVENT)
3039: zlog_debug ("make_hello: options: %x, int: %s",
3040: OPTIONS(oi), IF_NAME (oi));
3041:
3042: /* Set Options. */
3043: stream_putc (s, OPTIONS (oi));
3044:
3045: /* Set Router Priority. */
3046: stream_putc (s, PRIORITY (oi));
3047:
3048: /* Set Router Dead Interval. */
3049: stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3050:
3051: /* Set Designated Router. */
3052: stream_put_ipv4 (s, DR (oi).s_addr);
3053:
3054: p = stream_get_endp (s);
3055:
3056: /* Set Backup Designated Router. */
3057: stream_put_ipv4 (s, BDR (oi).s_addr);
3058:
3059: /* Add neighbor seen. */
3060: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3061: if ((nbr = rn->info))
3062: if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3063: if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3064: if (nbr->state != NSM_Down) /* This is myself for DR election. */
3065: if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
3066: {
3067: /* Check neighbor is sane? */
3068: if (nbr->d_router.s_addr != 0
3069: && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3070: && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3071: flag = 1;
3072:
3073: stream_put_ipv4 (s, nbr->router_id.s_addr);
3074: length += 4;
3075: }
3076:
3077: /* Let neighbor generate BackupSeen. */
3078: if (flag == 1)
3079: stream_putl_at (s, p, 0); /* ipv4 address, normally */
3080:
3081: return length;
3082: }
3083:
3084: static int
3085: ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3086: struct stream *s)
3087: {
3088: struct ospf_lsa *lsa;
3089: u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3090: u_char options;
3091: unsigned long pp;
3092: int i;
3093: struct ospf_lsdb *lsdb;
3094:
3095: /* Set Interface MTU. */
3096: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3097: stream_putw (s, 0);
3098: else
3099: stream_putw (s, oi->ifp->mtu);
3100:
3101: /* Set Options. */
3102: options = OPTIONS (oi);
3103: if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
1.1.1.5 ! misho 3104: SET_FLAG (options, OSPF_OPTION_O);
1.1 misho 3105: stream_putc (s, options);
3106:
3107: /* DD flags */
3108: pp = stream_get_endp (s);
3109: stream_putc (s, nbr->dd_flags);
3110:
3111: /* Set DD Sequence Number. */
3112: stream_putl (s, nbr->dd_seqnum);
3113:
3114: /* shortcut unneeded walk of (empty) summary LSDBs */
3115: if (ospf_db_summary_isempty (nbr))
3116: goto empty;
3117:
3118: /* Describe LSA Header from Database Summary List. */
3119: lsdb = &nbr->db_sum;
3120:
3121: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3122: {
3123: struct route_table *table = lsdb->type[i].db;
3124: struct route_node *rn;
3125:
3126: for (rn = route_top (table); rn; rn = route_next (rn))
3127: if ((lsa = rn->info) != NULL)
3128: {
3129: if (IS_OPAQUE_LSA (lsa->data->type)
3130: && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3131: {
3132: /* Suppress advertising opaque-informations. */
3133: /* Remove LSA from DB summary list. */
3134: ospf_lsdb_delete (lsdb, lsa);
3135: continue;
3136: }
3137:
3138: if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3139: {
3140: struct lsa_header *lsah;
3141: u_int16_t ls_age;
3142:
3143: /* DD packet overflows interface MTU. */
3144: if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
3145: break;
3146:
3147: /* Keep pointer to LS age. */
3148: lsah = (struct lsa_header *) (STREAM_DATA (s) +
3149: stream_get_endp (s));
3150:
3151: /* Proceed stream pointer. */
3152: stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3153: length += OSPF_LSA_HEADER_SIZE;
3154:
3155: /* Set LS age. */
3156: ls_age = LS_AGE (lsa);
3157: lsah->ls_age = htons (ls_age);
3158:
3159: }
3160:
3161: /* Remove LSA from DB summary list. */
3162: ospf_lsdb_delete (lsdb, lsa);
3163: }
3164: }
3165:
3166: /* Update 'More' bit */
3167: if (ospf_db_summary_isempty (nbr))
3168: {
3169: empty:
3170: if (nbr->state >= NSM_Exchange)
3171: {
3172: UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3173: /* Rewrite DD flags */
3174: stream_putc_at (s, pp, nbr->dd_flags);
3175: }
3176: else
3177: {
3178: assert (IS_SET_DD_M(nbr->dd_flags));
3179: }
3180: }
3181: return length;
3182: }
3183:
3184: static int
3185: ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3186: unsigned long delta, struct ospf_neighbor *nbr,
3187: struct ospf_lsa *lsa)
3188: {
3189: struct ospf_interface *oi;
3190:
3191: oi = nbr->oi;
3192:
3193: /* LS Request packet overflows interface MTU. */
3194: if (*length + delta > ospf_packet_max(oi))
3195: return 0;
3196:
3197: stream_putl (s, lsa->data->type);
3198: stream_put_ipv4 (s, lsa->data->id.s_addr);
3199: stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3200:
3201: ospf_lsa_unlock (&nbr->ls_req_last);
3202: nbr->ls_req_last = ospf_lsa_lock (lsa);
3203:
3204: *length += 12;
3205: return 1;
3206: }
3207:
3208: static int
3209: ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3210: {
3211: struct ospf_lsa *lsa;
3212: u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
3213: unsigned long delta = stream_get_endp(s)+12;
3214: struct route_table *table;
3215: struct route_node *rn;
3216: int i;
3217: struct ospf_lsdb *lsdb;
3218:
3219: lsdb = &nbr->ls_req;
3220:
3221: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3222: {
3223: table = lsdb->type[i].db;
3224: for (rn = route_top (table); rn; rn = route_next (rn))
3225: if ((lsa = (rn->info)) != NULL)
3226: if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3227: {
3228: route_unlock_node (rn);
3229: break;
3230: }
3231: }
3232: return length;
3233: }
3234:
3235: static int
3236: ls_age_increment (struct ospf_lsa *lsa, int delay)
3237: {
3238: int age;
3239:
3240: age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3241:
3242: return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3243: }
3244:
3245: static int
3246: ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
3247: {
3248: struct ospf_lsa *lsa;
3249: struct listnode *node;
3250: u_int16_t length = 0;
3251: unsigned int size_noauth;
3252: unsigned long delta = stream_get_endp (s);
3253: unsigned long pp;
3254: int count = 0;
3255:
3256: if (IS_DEBUG_OSPF_EVENT)
3257: zlog_debug ("ospf_make_ls_upd: Start");
3258:
3259: pp = stream_get_endp (s);
3260: stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
3261: length += OSPF_LS_UPD_MIN_SIZE;
3262:
3263: /* Calculate amount of packet usable for data. */
3264: size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3265:
3266: while ((node = listhead (update)) != NULL)
3267: {
3268: struct lsa_header *lsah;
3269: u_int16_t ls_age;
3270:
3271: if (IS_DEBUG_OSPF_EVENT)
1.1.1.5 ! misho 3272: zlog_debug ("ospf_make_ls_upd: List Iteration %d", count);
1.1 misho 3273:
3274: lsa = listgetdata (node);
3275:
3276: assert (lsa->data);
3277:
3278: /* Will it fit? */
3279: if (length + delta + ntohs (lsa->data->length) > size_noauth)
3280: break;
3281:
3282: /* Keep pointer to LS age. */
3283: lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
3284:
3285: /* Put LSA to Link State Request. */
3286: stream_put (s, lsa->data, ntohs (lsa->data->length));
3287:
3288: /* Set LS age. */
3289: /* each hop must increment an lsa_age by transmit_delay
3290: of OSPF interface */
3291: ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3292: lsah->ls_age = htons (ls_age);
3293:
3294: length += ntohs (lsa->data->length);
3295: count++;
3296:
3297: list_delete_node (update, node);
3298: ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
3299: }
3300:
3301: /* Now set #LSAs. */
3302: stream_putl_at (s, pp, count);
3303:
3304: if (IS_DEBUG_OSPF_EVENT)
3305: zlog_debug ("ospf_make_ls_upd: Stop");
3306: return length;
3307: }
3308:
3309: static int
3310: ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
3311: {
3312: struct listnode *node, *nnode;
3313: u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
3314: unsigned long delta = stream_get_endp(s) + 24;
3315: struct ospf_lsa *lsa;
3316:
3317: for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
3318: {
3319: assert (lsa);
3320:
3321: if (length + delta > ospf_packet_max (oi))
3322: break;
3323:
3324: stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3325: length += OSPF_LSA_HEADER_SIZE;
3326:
3327: listnode_delete (ack, lsa);
3328: ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
3329: }
3330:
3331: return length;
3332: }
3333:
3334: static void
3335: ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
3336: {
3337: struct ospf_packet *op;
3338: u_int16_t length = OSPF_HEADER_SIZE;
3339:
3340: op = ospf_packet_new (oi->ifp->mtu);
3341:
3342: /* Prepare OSPF common header. */
3343: ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3344:
3345: /* Prepare OSPF Hello body. */
3346: length += ospf_make_hello (oi, op->s);
3347:
3348: /* Fill OSPF header. */
3349: ospf_fill_header (oi, op->s, length);
3350:
3351: /* Set packet length. */
3352: op->length = length;
3353:
3354: op->dst.s_addr = addr;
3355:
3356: /* Add packet to the top of the interface output queue, so that they
3357: * can't get delayed by things like long queues of LS Update packets
3358: */
3359: ospf_packet_add_top (oi, op);
3360:
3361: /* Hook thread to write packet. */
3362: OSPF_ISM_WRITE_ON (oi->ospf);
3363: }
3364:
3365: static void
3366: ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3367: {
3368: struct ospf_interface *oi;
3369:
3370: oi = nbr_nbma->oi;
3371: assert(oi);
3372:
3373: /* If this is passive interface, do not send OSPF Hello. */
3374: if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
3375: return;
3376:
3377: if (oi->type != OSPF_IFTYPE_NBMA)
3378: return;
3379:
3380: if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3381: return;
3382:
3383: if (PRIORITY(oi) == 0)
3384: return;
3385:
3386: if (nbr_nbma->priority == 0
3387: && oi->state != ISM_DR && oi->state != ISM_Backup)
3388: return;
3389:
3390: ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
3391: }
3392:
3393: int
3394: ospf_poll_timer (struct thread *thread)
3395: {
3396: struct ospf_nbr_nbma *nbr_nbma;
3397:
3398: nbr_nbma = THREAD_ARG (thread);
3399: nbr_nbma->t_poll = NULL;
3400:
3401: if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
3402: zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
3403: IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3404:
3405: ospf_poll_send (nbr_nbma);
3406:
3407: if (nbr_nbma->v_poll > 0)
3408: OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3409: nbr_nbma->v_poll);
3410:
3411: return 0;
3412: }
3413:
3414:
3415: int
3416: ospf_hello_reply_timer (struct thread *thread)
3417: {
3418: struct ospf_neighbor *nbr;
3419:
3420: nbr = THREAD_ARG (thread);
3421: nbr->t_hello_reply = NULL;
3422:
3423: assert (nbr->oi);
3424:
3425: if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
3426: zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
3427: IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3428:
3429: ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
3430:
3431: return 0;
3432: }
3433:
3434: /* Send OSPF Hello. */
3435: void
3436: ospf_hello_send (struct ospf_interface *oi)
3437: {
3438: /* If this is passive interface, do not send OSPF Hello. */
3439: if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
3440: return;
3441:
3442: if (oi->type == OSPF_IFTYPE_NBMA)
3443: {
3444: struct ospf_neighbor *nbr;
3445: struct route_node *rn;
3446:
3447: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3448: if ((nbr = rn->info))
3449: if (nbr != oi->nbr_self)
3450: if (nbr->state != NSM_Down)
3451: {
3452: /* RFC 2328 Section 9.5.1
3453: If the router is not eligible to become Designated Router,
3454: it must periodically send Hello Packets to both the
3455: Designated Router and the Backup Designated Router (if they
3456: exist). */
3457: if (PRIORITY(oi) == 0 &&
3458: IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3459: IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3460: continue;
3461:
3462: /* If the router is eligible to become Designated Router, it
3463: must periodically send Hello Packets to all neighbors that
3464: are also eligible. In addition, if the router is itself the
3465: Designated Router or Backup Designated Router, it must also
3466: send periodic Hello Packets to all other neighbors. */
3467:
3468: if (nbr->priority == 0 && oi->state == ISM_DROther)
3469: continue;
3470: /* if oi->state == Waiting, send hello to all neighbors */
3471: ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
3472: }
3473: }
3474: else
3475: {
3476: /* Decide destination address. */
3477: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3478: ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3479: else
3480: ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
3481: }
3482: }
3483:
3484: /* Send OSPF Database Description. */
3485: void
3486: ospf_db_desc_send (struct ospf_neighbor *nbr)
3487: {
3488: struct ospf_interface *oi;
3489: struct ospf_packet *op;
3490: u_int16_t length = OSPF_HEADER_SIZE;
3491:
3492: oi = nbr->oi;
3493: op = ospf_packet_new (oi->ifp->mtu);
3494:
3495: /* Prepare OSPF common header. */
3496: ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3497:
3498: /* Prepare OSPF Database Description body. */
3499: length += ospf_make_db_desc (oi, nbr, op->s);
3500:
3501: /* Fill OSPF header. */
3502: ospf_fill_header (oi, op->s, length);
3503:
3504: /* Set packet length. */
3505: op->length = length;
3506:
3507: /* Decide destination address. */
3508: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3509: op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3510: else
3511: op->dst = nbr->address.u.prefix4;
3512:
3513: /* Add packet to the interface output queue. */
3514: ospf_packet_add (oi, op);
3515:
3516: /* Hook thread to write packet. */
3517: OSPF_ISM_WRITE_ON (oi->ospf);
3518:
3519: /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3520: if (nbr->last_send)
3521: ospf_packet_free (nbr->last_send);
3522: nbr->last_send = ospf_packet_dup (op);
3523: quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
3524: }
3525:
3526: /* Re-send Database Description. */
3527: void
3528: ospf_db_desc_resend (struct ospf_neighbor *nbr)
3529: {
3530: struct ospf_interface *oi;
3531:
3532: oi = nbr->oi;
3533:
3534: /* Add packet to the interface output queue. */
3535: ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3536:
3537: /* Hook thread to write packet. */
3538: OSPF_ISM_WRITE_ON (oi->ospf);
3539: }
3540:
3541: /* Send Link State Request. */
3542: void
3543: ospf_ls_req_send (struct ospf_neighbor *nbr)
3544: {
3545: struct ospf_interface *oi;
3546: struct ospf_packet *op;
3547: u_int16_t length = OSPF_HEADER_SIZE;
3548:
3549: oi = nbr->oi;
3550: op = ospf_packet_new (oi->ifp->mtu);
3551:
3552: /* Prepare OSPF common header. */
3553: ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3554:
3555: /* Prepare OSPF Link State Request body. */
3556: length += ospf_make_ls_req (nbr, op->s);
3557: if (length == OSPF_HEADER_SIZE)
3558: {
3559: ospf_packet_free (op);
3560: return;
3561: }
3562:
3563: /* Fill OSPF header. */
3564: ospf_fill_header (oi, op->s, length);
3565:
3566: /* Set packet length. */
3567: op->length = length;
3568:
3569: /* Decide destination address. */
3570: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3571: op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3572: else
3573: op->dst = nbr->address.u.prefix4;
3574:
3575: /* Add packet to the interface output queue. */
3576: ospf_packet_add (oi, op);
3577:
3578: /* Hook thread to write packet. */
3579: OSPF_ISM_WRITE_ON (oi->ospf);
3580:
3581: /* Add Link State Request Retransmission Timer. */
3582: OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3583: }
3584:
3585: /* Send Link State Update with an LSA. */
3586: void
3587: ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3588: int flag)
3589: {
3590: struct list *update;
3591:
3592: update = list_new ();
3593:
3594: listnode_add (update, lsa);
3595: ospf_ls_upd_send (nbr, update, flag);
3596:
3597: list_delete (update);
3598: }
3599:
3600: /* Determine size for packet. Must be at least big enough to accomodate next
3601: * LSA on list, which may be bigger than MTU size.
3602: *
3603: * Return pointer to new ospf_packet
3604: * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3605: * on packet sizes (in which case offending LSA is deleted from update list)
3606: */
3607: static struct ospf_packet *
3608: ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3609: {
3610: struct ospf_lsa *lsa;
3611: struct listnode *ln;
3612: size_t size;
3613: static char warned = 0;
3614:
3615: lsa = listgetdata((ln = listhead (update)));
3616: assert (lsa->data);
3617:
3618: if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3619: > ospf_packet_max (oi))
3620: {
3621: if (!warned)
3622: {
3623: zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3624: "will need to fragment. Not optimal. Try divide up"
3625: " your network with areas. Use 'debug ospf packet send'"
3626: " to see details, or look at 'show ip ospf database ..'");
3627: warned = 1;
3628: }
3629:
3630: if (IS_DEBUG_OSPF_PACKET (0, SEND))
3631: zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3632: " %d bytes originated by %s, will be fragmented!",
3633: inet_ntoa (lsa->data->id),
3634: ntohs (lsa->data->length),
3635: inet_ntoa (lsa->data->adv_router));
3636:
3637: /*
3638: * Allocate just enough to fit this LSA only, to avoid including other
3639: * LSAs in fragmented LSA Updates.
3640: */
3641: size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3642: + OSPF_LS_UPD_MIN_SIZE;
3643: }
3644: else
3645: size = oi->ifp->mtu;
3646:
3647: if (size > OSPF_MAX_PACKET_SIZE)
3648: {
3649: zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3650: " %d bytes, packet size %ld, dropping it completely."
3651: " OSPF routing is broken!",
3652: inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
3653: (long int) size);
3654: list_delete_node (update, ln);
3655: return NULL;
3656: }
3657:
3658: /* IP header is built up separately by ospf_write(). This means, that we must
3659: * reduce the "affordable" size just calculated by length of an IP header.
3660: * This makes sure, that even if we manage to fill the payload with LSA data
3661: * completely, the final packet (our data plus IP header) still fits into
3662: * outgoing interface MTU. This correction isn't really meaningful for an
3663: * oversized LSA, but for consistency the correction is done for both cases.
3664: *
3665: * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3666: */
3667: return ospf_packet_new (size - sizeof (struct ip));
3668: }
3669:
3670: static void
3671: ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
3672: struct in_addr addr)
3673: {
3674: struct ospf_packet *op;
3675: u_int16_t length = OSPF_HEADER_SIZE;
3676:
3677: if (IS_DEBUG_OSPF_EVENT)
1.1.1.5 ! misho 3678: zlog_debug ("listcount = %d, [%s]dst %s", listcount (update), IF_NAME(oi),
! 3679: inet_ntoa(addr));
1.1 misho 3680:
3681: op = ospf_ls_upd_packet_new (update, oi);
3682:
3683: /* Prepare OSPF common header. */
3684: ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3685:
3686: /* Prepare OSPF Link State Update body.
3687: * Includes Type-7 translation.
3688: */
3689: length += ospf_make_ls_upd (oi, update, op->s);
3690:
3691: /* Fill OSPF header. */
3692: ospf_fill_header (oi, op->s, length);
3693:
3694: /* Set packet length. */
3695: op->length = length;
3696:
3697: /* Decide destination address. */
3698: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3699: op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3700: else
3701: op->dst.s_addr = addr.s_addr;
3702:
3703: /* Add packet to the interface output queue. */
3704: ospf_packet_add (oi, op);
3705:
3706: /* Hook thread to write packet. */
3707: OSPF_ISM_WRITE_ON (oi->ospf);
3708: }
3709:
3710: static int
3711: ospf_ls_upd_send_queue_event (struct thread *thread)
3712: {
3713: struct ospf_interface *oi = THREAD_ARG(thread);
3714: struct route_node *rn;
3715: struct route_node *rnext;
3716: struct list *update;
3717: char again = 0;
3718:
3719: oi->t_ls_upd_event = NULL;
3720:
3721: if (IS_DEBUG_OSPF_EVENT)
3722: zlog_debug ("ospf_ls_upd_send_queue start");
3723:
3724: for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
3725: {
3726: rnext = route_next (rn);
3727:
3728: if (rn->info == NULL)
3729: continue;
3730:
3731: update = (struct list *)rn->info;
3732:
3733: ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
3734:
3735: /* list might not be empty. */
3736: if (listcount(update) == 0)
3737: {
3738: list_delete (rn->info);
3739: rn->info = NULL;
3740: route_unlock_node (rn);
3741: }
3742: else
3743: again = 1;
3744: }
3745:
3746: if (again != 0)
3747: {
3748: if (IS_DEBUG_OSPF_EVENT)
3749: zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
3750: " %d nodes to try again, raising new event", again);
3751: oi->t_ls_upd_event =
3752: thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3753: }
3754:
3755: if (IS_DEBUG_OSPF_EVENT)
3756: zlog_debug ("ospf_ls_upd_send_queue stop");
3757:
3758: return 0;
3759: }
3760:
3761: void
3762: ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
3763: {
3764: struct ospf_interface *oi;
3765: struct ospf_lsa *lsa;
3766: struct prefix_ipv4 p;
3767: struct route_node *rn;
3768: struct listnode *node;
3769:
3770: oi = nbr->oi;
3771:
3772: p.family = AF_INET;
3773: p.prefixlen = IPV4_MAX_BITLEN;
3774:
3775: /* Decide destination address. */
3776: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3777: p.prefix = oi->vl_data->peer_addr;
3778: else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3779: p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3780: else if (flag == OSPF_SEND_PACKET_DIRECT)
3781: p.prefix = nbr->address.u.prefix4;
3782: else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3783: p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3784: else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3785: p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3786: else
3787: p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3788:
3789: if (oi->type == OSPF_IFTYPE_NBMA)
3790: {
3791: if (flag == OSPF_SEND_PACKET_INDIRECT)
3792: zlog_warn ("* LS-Update is directly sent on NBMA network.");
3793: if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3794: zlog_warn ("* LS-Update is sent to myself.");
3795: }
3796:
3797: rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3798:
3799: if (rn->info == NULL)
3800: rn->info = list_new ();
1.1.1.5 ! misho 3801: else
! 3802: route_unlock_node (rn);
1.1 misho 3803:
3804: for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3805: listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
3806:
3807: if (oi->t_ls_upd_event == NULL)
3808: oi->t_ls_upd_event =
3809: thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3810: }
3811:
3812: static void
3813: ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3814: struct in_addr dst)
3815: {
3816: struct ospf_packet *op;
3817: u_int16_t length = OSPF_HEADER_SIZE;
3818:
3819: op = ospf_packet_new (oi->ifp->mtu);
3820:
3821: /* Prepare OSPF common header. */
3822: ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3823:
3824: /* Prepare OSPF Link State Acknowledgment body. */
3825: length += ospf_make_ls_ack (oi, ack, op->s);
3826:
3827: /* Fill OSPF header. */
3828: ospf_fill_header (oi, op->s, length);
3829:
3830: /* Set packet length. */
3831: op->length = length;
3832:
3833: /* Set destination IP address. */
3834: op->dst = dst;
3835:
3836: /* Add packet to the interface output queue. */
3837: ospf_packet_add (oi, op);
3838:
3839: /* Hook thread to write packet. */
3840: OSPF_ISM_WRITE_ON (oi->ospf);
3841: }
3842:
3843: static int
3844: ospf_ls_ack_send_event (struct thread *thread)
3845: {
3846: struct ospf_interface *oi = THREAD_ARG (thread);
3847:
3848: oi->t_ls_ack_direct = NULL;
3849:
3850: while (listcount (oi->ls_ack_direct.ls_ack))
3851: ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3852: oi->ls_ack_direct.dst);
3853:
3854: return 0;
3855: }
3856:
3857: void
3858: ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3859: {
3860: struct ospf_interface *oi = nbr->oi;
3861:
3862: if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3863: oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3864:
3865: listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3866:
3867: if (oi->t_ls_ack_direct == NULL)
3868: oi->t_ls_ack_direct =
3869: thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3870: }
3871:
3872: /* Send Link State Acknowledgment delayed. */
3873: void
3874: ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3875: {
3876: struct in_addr dst;
3877:
3878: /* Decide destination address. */
3879: /* RFC2328 Section 13.5 On non-broadcast
3880: networks, delayed Link State Acknowledgment packets must be
3881: unicast separately over each adjacency (i.e., neighbor whose
3882: state is >= Exchange). */
3883: if (oi->type == OSPF_IFTYPE_NBMA)
3884: {
3885: struct ospf_neighbor *nbr;
3886: struct route_node *rn;
3887:
3888: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3889: if ((nbr = rn->info) != NULL)
3890: if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3891: while (listcount (oi->ls_ack))
3892: ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3893: return;
3894: }
3895: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3896: dst.s_addr = oi->vl_data->peer_addr.s_addr;
3897: else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3898: dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3899: else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3900: dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3901: else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3902: dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3903: else
3904: dst.s_addr = htonl (OSPF_ALLDROUTERS);
3905:
3906: while (listcount (oi->ls_ack))
3907: ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3908: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>