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