Annotation of embedaddon/quagga/ospfd/ospf_packet.c, revision 1.1.1.4
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;
1.1.1.4 ! misho 1593: if (! ospf_lsa_checksum_valid (lsah))
1.1 misho 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:
1.1.1.4 ! misho 1764: /* Process each LSA received in the one packet.
! 1765: *
! 1766: * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
! 1767: * text below are from the steps in RFC 2328, Section 13.
! 1768: */
1.1 misho 1769: for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1770: {
1771: struct ospf_lsa *ls_ret, *current;
1772: int ret = 1;
1773:
1774: if (IS_DEBUG_OSPF_NSSA)
1775: {
1776: char buf1[INET_ADDRSTRLEN];
1777: char buf2[INET_ADDRSTRLEN];
1778: char buf3[INET_ADDRSTRLEN];
1779:
1780: zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
1781: lsa->data->type,
1782: inet_ntop (AF_INET, &ospfh->router_id,
1783: buf1, INET_ADDRSTRLEN),
1784: inet_ntop (AF_INET, &lsa->data->id,
1785: buf2, INET_ADDRSTRLEN),
1786: inet_ntop (AF_INET, &lsa->data->adv_router,
1787: buf3, INET_ADDRSTRLEN));
1788: }
1789:
1790: listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1791:
1.1.1.4 ! misho 1792: /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1.1 misho 1793:
1.1.1.4 ! misho 1794: /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
1.1 misho 1795:
1.1.1.4 ! misho 1796: /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */
1.1 misho 1797:
1798: /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1799:
1800: /* Do take in Type-7's if we are an NSSA */
1801:
1802: /* If we are also an ABR, later translate them to a Type-5 packet */
1803:
1804: /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1805: translate them to a separate Type-5 packet. */
1806:
1807: if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1808: /* Reject from STUB or NSSA */
1809: if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1810: {
1811: if (IS_DEBUG_OSPF_NSSA)
1812: zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
1813: DISCARD_LSA (lsa, 1);
1814: }
1815:
1816: if (lsa->data->type == OSPF_AS_NSSA_LSA)
1817: if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1818: {
1819: if (IS_DEBUG_OSPF_NSSA)
1820: zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
1821: DISCARD_LSA (lsa,2);
1822: }
1823:
1824: /* Find the LSA in the current database. */
1825:
1826: current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1827:
1.1.1.4 ! misho 1828: /* (4) If the LSA's LS age is equal to MaxAge, and there is currently
1.1 misho 1829: no instance of the LSA in the router's link state database,
1830: and none of router's neighbors are in states Exchange or Loading,
1.1.1.4 ! misho 1831: then take the following actions: */
1.1 misho 1832:
1833: if (IS_LSA_MAXAGE (lsa) && !current &&
1834: (ospf_nbr_count (oi, NSM_Exchange) +
1835: ospf_nbr_count (oi, NSM_Loading)) == 0)
1836: {
1.1.1.4 ! misho 1837: /* (4a) Response Link State Acknowledgment. */
1.1 misho 1838: ospf_ls_ack_send (nbr, lsa);
1839:
1.1.1.4 ! misho 1840: /* (4b) Discard LSA. */
! 1841: if (IS_DEBUG_OSPF (lsa, LSA))
! 1842: {
! 1843: zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.",
! 1844: dump_lsa_key(lsa));
! 1845: }
1.1 misho 1846: DISCARD_LSA (lsa, 3);
1847: }
1848:
1849: #ifdef HAVE_OPAQUE_LSA
1850: if (IS_OPAQUE_LSA (lsa->data->type)
1851: && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
1852: {
1853: /*
1854: * Even if initial flushing seems to be completed, there might
1855: * be a case that self-originated LSA with MaxAge still remain
1856: * in the routing domain.
1857: * Just send an LSAck message to cease retransmission.
1858: */
1859: if (IS_LSA_MAXAGE (lsa))
1860: {
1861: zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1862: ospf_ls_ack_send (nbr, lsa);
1863: ospf_lsa_discard (lsa);
1864:
1865: if (current != NULL && ! IS_LSA_MAXAGE (current))
1866: ospf_opaque_lsa_refresh_schedule (current);
1867: continue;
1868: }
1869:
1870: /*
1871: * If an instance of self-originated Opaque-LSA is not found
1872: * in the LSDB, there are some possible cases here.
1873: *
1874: * 1) This node lost opaque-capability after restart.
1875: * 2) Else, a part of opaque-type is no more supported.
1876: * 3) Else, a part of opaque-id is no more supported.
1877: *
1878: * Anyway, it is still this node's responsibility to flush it.
1879: * Otherwise, the LSA instance remains in the routing domain
1880: * until its age reaches to MaxAge.
1881: */
1882: /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
1883: if (current == NULL)
1884: {
1885: if (IS_DEBUG_OSPF_EVENT)
1886: zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1887: "not found in the LSDB.", dump_lsa_key (lsa));
1888:
1889: SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1890:
1891: ospf_opaque_self_originated_lsa_received (nbr, lsa);
1892: ospf_ls_ack_send (nbr, lsa);
1893:
1894: continue;
1895: }
1896: }
1897: #endif /* HAVE_OPAQUE_LSA */
1898:
1899: /* It might be happen that received LSA is self-originated network LSA, but
1.1.1.4 ! misho 1900: * router ID is changed. So, we should check if LSA is a network-LSA whose
1.1 misho 1901: * Link State ID is one of the router's own IP interface addresses but whose
1902: * Advertising Router is not equal to the router's own Router ID
1903: * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1904: */
1905:
1906: if(lsa->data->type == OSPF_NETWORK_LSA)
1907: {
1908: struct listnode *oinode, *oinnode;
1909: struct ospf_interface *out_if;
1910: int Flag = 0;
1911:
1912: for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
1913: {
1914: if(out_if == NULL)
1915: break;
1916:
1917: if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1918: (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1919: {
1920: if(out_if->network_lsa_self)
1921: {
1922: ospf_lsa_flush_area(lsa,out_if->area);
1923: if(IS_DEBUG_OSPF_EVENT)
1924: zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
1925: lsa, (int) lsa->data->type);
1926: ospf_lsa_discard (lsa);
1927: Flag = 1;
1928: }
1929: break;
1930: }
1931: }
1932: if(Flag)
1933: continue;
1934: }
1935:
1936: /* (5) Find the instance of this LSA that is currently contained
1937: in the router's link state database. If there is no
1938: database copy, or the received LSA is more recent than
1.1.1.4 ! misho 1939: the database copy the following steps must be performed.
! 1940: (The sub steps from RFC 2328 section 13 step (5) will be performed in
! 1941: ospf_flood() ) */
1.1 misho 1942:
1943: if (current == NULL ||
1944: (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1945: {
1946: /* Actual flooding procedure. */
1947: if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
1948: DISCARD_LSA (lsa, 4);
1949: continue;
1950: }
1951:
1952: /* (6) Else, If there is an instance of the LSA on the sending
1953: neighbor's Link state request list, an error has occurred in
1954: the Database Exchange process. In this case, restart the
1955: Database Exchange process by generating the neighbor event
1956: BadLSReq for the sending neighbor and stop processing the
1957: Link State Update packet. */
1958:
1959: if (ospf_ls_request_lookup (nbr, lsa))
1960: {
1961: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1962: zlog_warn("LSA[%s] instance exists on Link state request list",
1963: dump_lsa_key(lsa));
1964:
1965: /* Clean list of LSAs. */
1966: ospf_upd_list_clean (lsas);
1967: /* this lsa is not on lsas list already. */
1968: ospf_lsa_discard (lsa);
1969: return;
1970: }
1971:
1972: /* If the received LSA is the same instance as the database copy
1973: (i.e., neither one is more recent) the following two steps
1974: should be performed: */
1975:
1976: if (ret == 0)
1977: {
1978: /* If the LSA is listed in the Link state retransmission list
1979: for the receiving adjacency, the router itself is expecting
1980: an acknowledgment for this LSA. The router should treat the
1981: received LSA as an acknowledgment by removing the LSA from
1982: the Link state retransmission list. This is termed an
1983: "implied acknowledgment". */
1984:
1985: ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1986:
1987: if (ls_ret != NULL)
1988: {
1989: ospf_ls_retransmit_delete (nbr, ls_ret);
1990:
1991: /* Delayed acknowledgment sent if advertisement received
1992: from Designated Router, otherwise do nothing. */
1993: if (oi->state == ISM_Backup)
1994: if (NBR_IS_DR (nbr))
1995: listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1996:
1997: DISCARD_LSA (lsa, 5);
1998: }
1999: else
2000: /* Acknowledge the receipt of the LSA by sending a
2001: Link State Acknowledgment packet back out the receiving
2002: interface. */
2003: {
2004: ospf_ls_ack_send (nbr, lsa);
2005: DISCARD_LSA (lsa, 6);
2006: }
2007: }
2008:
2009: /* The database copy is more recent. If the database copy
2010: has LS age equal to MaxAge and LS sequence number equal to
2011: MaxSequenceNumber, simply discard the received LSA without
2012: acknowledging it. (In this case, the LSA's LS sequence number is
2013: wrapping, and the MaxSequenceNumber LSA must be completely
2014: flushed before any new LSA instance can be introduced). */
2015:
2016: else if (ret > 0) /* Database copy is more recent */
2017: {
2018: if (IS_LSA_MAXAGE (current) &&
2019: current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
2020: {
2021: DISCARD_LSA (lsa, 7);
2022: }
2023: /* Otherwise, as long as the database copy has not been sent in a
2024: Link State Update within the last MinLSArrival seconds, send the
2025: database copy back to the sending neighbor, encapsulated within
2026: a Link State Update Packet. The Link State Update Packet should
2027: be sent directly to the neighbor. In so doing, do not put the
2028: database copy of the LSA on the neighbor's link state
2029: retransmission list, and do not acknowledge the received (less
2030: recent) LSA instance. */
2031: else
2032: {
2033: struct timeval now;
2034:
2035: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
2036:
2037: if (tv_cmp (tv_sub (now, current->tv_orig),
2038: int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
2039: /* Trap NSSA type later.*/
2040: ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
2041: DISCARD_LSA (lsa, 8);
2042: }
2043: }
2044: }
2045: #undef DISCARD_LSA
2046:
2047: assert (listcount (lsas) == 0);
2048: list_delete (lsas);
2049: }
2050:
2051: /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
2052: static void
2053: ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
2054: struct stream *s, struct ospf_interface *oi, u_int16_t size)
2055: {
2056: struct ospf_neighbor *nbr;
2057:
2058: /* increment statistics. */
2059: oi->ls_ack_in++;
2060:
2061: nbr = ospf_nbr_lookup (oi, iph, ospfh);
2062: if (nbr == NULL)
2063: {
2064: zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
2065: inet_ntoa (ospfh->router_id));
2066: return;
2067: }
2068:
2069: /* Add event to thread. */
2070: OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
2071:
2072: if (nbr->state < NSM_Exchange)
2073: {
2074: zlog_warn ("Link State Acknowledgment: "
2075: "Neighbor[%s] state %s is less than Exchange",
2076: inet_ntoa (ospfh->router_id),
2077: LOOKUP(ospf_nsm_state_msg, nbr->state));
2078: return;
2079: }
2080:
2081: while (size >= OSPF_LSA_HEADER_SIZE)
2082: {
2083: struct ospf_lsa *lsa, *lsr;
2084:
2085: lsa = ospf_lsa_new ();
2086: lsa->data = (struct lsa_header *) STREAM_PNT (s);
2087:
2088: /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2089: size -= OSPF_LSA_HEADER_SIZE;
2090: stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
2091:
2092: if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2093: {
2094: lsa->data = NULL;
2095: ospf_lsa_discard (lsa);
2096: continue;
2097: }
2098:
2099: lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2100:
2101: if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2102: {
2103: #ifdef HAVE_OPAQUE_LSA
2104: if (IS_OPAQUE_LSA (lsr->data->type))
2105: ospf_opaque_ls_ack_received (nbr, lsr);
2106: #endif /* HAVE_OPAQUE_LSA */
2107:
2108: ospf_ls_retransmit_delete (nbr, lsr);
2109: }
2110:
2111: lsa->data = NULL;
2112: ospf_lsa_discard (lsa);
2113: }
2114:
2115: return;
2116: }
2117:
2118: static struct stream *
2119: ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
2120: {
2121: int ret;
2122: struct ip *iph;
2123: u_int16_t ip_len;
2124: unsigned int ifindex = 0;
2125: struct iovec iov;
2126: /* Header and data both require alignment. */
2127: char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2128: struct msghdr msgh;
2129:
2130: memset (&msgh, 0, sizeof (struct msghdr));
2131: msgh.msg_iov = &iov;
2132: msgh.msg_iovlen = 1;
2133: msgh.msg_control = (caddr_t) buff;
2134: msgh.msg_controllen = sizeof (buff);
2135:
2136: ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2137: if (ret < 0)
2138: {
2139: zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2140: return NULL;
2141: }
2142: if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
2143: {
2144: zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2145: "(ip header size is %u)",
2146: ret, (u_int)sizeof(iph));
2147: return NULL;
2148: }
2149:
2150: /* Note that there should not be alignment problems with this assignment
2151: because this is at the beginning of the stream data buffer. */
2152: iph = (struct ip *) STREAM_DATA(ibuf);
2153: sockopt_iphdrincl_swab_systoh (iph);
2154:
2155: ip_len = iph->ip_len;
2156:
1.1.1.3 misho 2157: #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
1.1 misho 2158: /*
2159: * Kernel network code touches incoming IP header parameters,
2160: * before protocol specific processing.
2161: *
2162: * 1) Convert byteorder to host representation.
2163: * --> ip_len, ip_id, ip_off
2164: *
2165: * 2) Adjust ip_len to strip IP header size!
2166: * --> If user process receives entire IP packet via RAW
2167: * socket, it must consider adding IP header size to
2168: * the "ip_len" field of "ip" structure.
2169: *
2170: * For more details, see <netinet/ip_input.c>.
2171: */
2172: ip_len = ip_len + (iph->ip_hl << 2);
2173: #endif
2174:
2175: #if defined(__DragonFly__)
2176: /*
2177: * in DragonFly's raw socket, ip_len/ip_off are read
2178: * in network byte order.
2179: * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2180: */
2181: ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2182: #endif
2183:
2184: ifindex = getsockopt_ifindex (AF_INET, &msgh);
2185:
2186: *ifp = if_lookup_by_index (ifindex);
2187:
2188: if (ret != ip_len)
2189: {
2190: zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2191: "but recvmsg returned %d", ip_len, ret);
2192: return NULL;
2193: }
2194:
2195: return ibuf;
2196: }
2197:
2198: static struct ospf_interface *
2199: ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
2200: struct ip *iph, struct ospf_header *ospfh)
2201: {
2202: struct ospf_interface *rcv_oi;
2203: struct ospf_vl_data *vl_data;
2204: struct ospf_area *vl_area;
2205: struct listnode *node;
2206:
2207: if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2208: !OSPF_IS_AREA_BACKBONE (ospfh))
2209: return NULL;
2210:
2211: /* look for local OSPF interface matching the destination
2212: * to determine Area ID. We presume therefore the destination address
2213: * is unique, or at least (for "unnumbered" links), not used in other
2214: * areas
2215: */
2216: if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2217: iph->ip_dst)) == NULL)
2218: return NULL;
2219:
2220: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
2221: {
2222: vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
2223: if (!vl_area)
2224: continue;
2225:
2226: if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2227: IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2228: {
2229: if (IS_DEBUG_OSPF_EVENT)
2230: zlog_debug ("associating packet with %s",
2231: IF_NAME (vl_data->vl_oi));
2232: if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2233: {
2234: if (IS_DEBUG_OSPF_EVENT)
2235: zlog_debug ("This VL is not up yet, sorry");
2236: return NULL;
2237: }
2238:
2239: return vl_data->vl_oi;
2240: }
2241: }
2242:
2243: if (IS_DEBUG_OSPF_EVENT)
2244: zlog_debug ("couldn't find any VL to associate the packet with");
2245:
2246: return NULL;
2247: }
2248:
1.1.1.3 misho 2249: static int
1.1 misho 2250: ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2251: {
2252: /* Check match the Area ID of the receiving interface. */
2253: if (OSPF_AREA_SAME (&oi->area, &ospfh))
2254: return 1;
2255:
2256: return 0;
2257: }
2258:
2259: /* Unbound socket will accept any Raw IP packets if proto is matched.
2260: To prevent it, compare src IP address and i/f address with masking
2261: i/f network mask. */
2262: static int
2263: ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2264: {
2265: struct in_addr mask, me, him;
2266:
2267: if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2268: oi->type == OSPF_IFTYPE_VIRTUALLINK)
2269: return 1;
2270:
2271: masklen2ip (oi->address->prefixlen, &mask);
2272:
2273: me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2274: him.s_addr = ip_src.s_addr & mask.s_addr;
2275:
2276: if (IPV4_ADDR_SAME (&me, &him))
2277: return 1;
2278:
2279: return 0;
2280: }
2281:
1.1.1.2 misho 2282: /* Return 1, if the packet is properly authenticated and checksummed,
2283: 0 otherwise. In particular, check that AuType header field is valid and
2284: matches the locally configured AuType, and that D.5 requirements are met. */
1.1 misho 2285: static int
1.1.1.2 misho 2286: ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
1.1 misho 2287: {
2288: struct crypt_key *ck;
1.1.1.2 misho 2289: u_int16_t iface_auth_type;
2290: u_int16_t pkt_auth_type = ntohs (ospfh->auth_type);
1.1 misho 2291:
1.1.1.2 misho 2292: switch (pkt_auth_type)
2293: {
2294: case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
2295: if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))
1.1 misho 2296: {
1.1.1.2 misho 2297: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2298: zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null",
2299: IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2300: return 0;
1.1 misho 2301: }
1.1.1.2 misho 2302: if (! ospf_check_sum (ospfh))
2303: {
2304: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2305: zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s",
2306: IF_NAME (oi), inet_ntoa (ospfh->router_id));
2307: return 0;
2308: }
2309: return 1;
2310: case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */
2311: if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi)))
2312: {
2313: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2314: zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple",
2315: IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2316: return 0;
2317: }
2318: if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2319: {
2320: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2321: zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi));
2322: return 0;
2323: }
2324: if (! ospf_check_sum (ospfh))
2325: {
2326: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2327: zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s",
2328: IF_NAME (oi), inet_ntoa (ospfh->router_id));
2329: return 0;
2330: }
2331: return 1;
2332: case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */
2333: if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi)))
2334: {
2335: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2336: zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2337: IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type));
2338: return 0;
2339: }
2340: if (ospfh->checksum)
2341: {
2342: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2343: zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi));
2344: return 0;
2345: }
2346: /* only MD5 crypto method can pass ospf_packet_examin() */
2347: if
2348: (
2349: NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) ||
2350: ospfh->u.crypt.key_id != ck->key_id ||
2351: /* Condition above uses the last key ID on the list, which is
2352: different from what ospf_crypt_key_lookup() does. A bug? */
2353: ! ospf_check_md5_digest (oi, ospfh)
2354: )
2355: {
2356: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2357: zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi));
2358: return 0;
2359: }
2360: return 1;
2361: default:
2362: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2363: zlog_warn ("interface %s: invalid packet auth-type (%02x)",
2364: IF_NAME (oi), pkt_auth_type);
2365: return 0;
2366: }
1.1 misho 2367: }
2368:
2369: static int
2370: ospf_check_sum (struct ospf_header *ospfh)
2371: {
2372: u_int32_t ret;
2373: u_int16_t sum;
2374:
2375: /* clear auth_data for checksum. */
2376: memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2377:
2378: /* keep checksum and clear. */
2379: sum = ospfh->checksum;
2380: memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2381:
2382: /* calculate checksum. */
2383: ret = in_cksum (ospfh, ntohs (ospfh->length));
2384:
2385: if (ret != sum)
2386: {
2387: zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2388: ret, sum);
2389: return 0;
2390: }
2391:
2392: return 1;
2393: }
2394:
1.1.1.2 misho 2395: /* Verify, that given link/TOS records are properly sized/aligned and match
2396: Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2397: static unsigned
2398: ospf_router_lsa_links_examin
2399: (
2400: struct router_lsa_link * link,
2401: u_int16_t linkbytes,
2402: const u_int16_t num_links
2403: )
1.1 misho 2404: {
1.1.1.2 misho 2405: unsigned counted_links = 0, thislinklen;
2406:
2407: while (linkbytes)
2408: {
2409: thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count;
2410: if (thislinklen > linkbytes)
1.1 misho 2411: {
1.1.1.2 misho 2412: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2413: zlog_debug ("%s: length error in link block #%u", __func__, counted_links);
2414: return MSG_NG;
1.1 misho 2415: }
1.1.1.2 misho 2416: link = (struct router_lsa_link *)((caddr_t) link + thislinklen);
2417: linkbytes -= thislinklen;
2418: counted_links++;
2419: }
2420: if (counted_links != num_links)
2421: {
2422: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2423: zlog_debug ("%s: %u link blocks declared, %u present",
2424: __func__, num_links, counted_links);
2425: return MSG_NG;
2426: }
2427: return MSG_OK;
2428: }
1.1 misho 2429:
1.1.1.2 misho 2430: /* Verify, that the given LSA is properly sized/aligned (including type-specific
2431: minimum length constraint). */
2432: static unsigned
2433: ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly)
2434: {
2435: unsigned ret;
2436: struct router_lsa * rlsa;
2437: if
2438: (
2439: lsah->type < OSPF_MAX_LSA &&
2440: ospf_lsa_minlen[lsah->type] &&
2441: lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]
2442: )
1.1 misho 2443: {
1.1.1.2 misho 2444: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2445: zlog_debug ("%s: undersized (%u B) %s",
2446: __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type));
2447: return MSG_NG;
2448: }
2449: switch (lsah->type)
2450: {
2451: case OSPF_ROUTER_LSA:
2452: /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */
2453: if (headeronly)
2454: {
2455: ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2456: break;
2457: }
2458: rlsa = (struct router_lsa *) lsah;
2459: ret = ospf_router_lsa_links_examin
2460: (
2461: (struct router_lsa_link *) rlsa->link,
2462: lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */
2463: ntohs (rlsa->links) /* 16 bits */
2464: );
2465: break;
2466: case OSPF_AS_EXTERNAL_LSA:
2467: /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */
2468: case OSPF_AS_NSSA_LSA:
2469: /* RFC3101 C, idem */
2470: ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK;
2471: break;
2472: /* Following LSA types are considered OK length-wise as soon as their minimum
2473: * length constraint is met and length of the whole LSA is a multiple of 4
2474: * (basic LSA header size is already a multiple of 4). */
2475: case OSPF_NETWORK_LSA:
2476: /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2477: case OSPF_SUMMARY_LSA:
2478: case OSPF_ASBR_SUMMARY_LSA:
2479: /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */
2480: #ifdef HAVE_OPAQUE_LSA
2481: case OSPF_OPAQUE_LINK_LSA:
2482: case OSPF_OPAQUE_AREA_LSA:
2483: case OSPF_OPAQUE_AS_LSA:
2484: /* RFC5250 A.2, "some number of octets (of application-specific
2485: * data) padded to 32-bit alignment." This is considered equivalent
2486: * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt
2487: * file for the detailed analysis of this passage. */
2488: #endif
2489: ret = lsalen % 4 ? MSG_NG : MSG_OK;
2490: break;
2491: default:
2492: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2493: zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type);
2494: return MSG_NG;
2495: }
2496: if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2497: zlog_debug ("%s: alignment error in %s",
2498: __func__, LOOKUP (ospf_lsa_type_msg, lsah->type));
2499: return ret;
2500: }
2501:
2502: /* Verify if the provided input buffer is a valid sequence of LSAs. This
2503: includes verification of LSA blocks length/alignment and dispatching
2504: of deeper-level checks. */
2505: static unsigned
2506: ospf_lsaseq_examin
2507: (
2508: struct lsa_header *lsah, /* start of buffered data */
2509: size_t length,
2510: const u_char headeronly,
2511: /* When declared_num_lsas is not 0, compare it to the real number of LSAs
2512: and treat the difference as an error. */
2513: const u_int32_t declared_num_lsas
2514: )
2515: {
2516: u_int32_t counted_lsas = 0;
2517:
2518: while (length)
2519: {
2520: u_int16_t lsalen;
2521: if (length < OSPF_LSA_HEADER_SIZE)
2522: {
2523: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2524: zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
2525: __func__, length, counted_lsas);
2526: return MSG_NG;
2527: }
2528: /* save on ntohs() calls here and in the LSA validator */
2529: lsalen = ntohs (lsah->length);
2530: if (lsalen < OSPF_LSA_HEADER_SIZE)
2531: {
2532: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2533: zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
2534: __func__, counted_lsas, lsalen);
2535: return MSG_NG;
2536: }
2537: if (headeronly)
2538: {
2539: /* less checks here and in ospf_lsa_examin() */
2540: if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1))
2541: {
2542: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2543: zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas);
2544: return MSG_NG;
2545: }
2546: lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE);
2547: length -= OSPF_LSA_HEADER_SIZE;
2548: }
2549: else
2550: {
2551: /* make sure the input buffer is deep enough before further checks */
2552: if (lsalen > length)
2553: {
2554: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2555: zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2556: __func__, counted_lsas, lsalen, length);
2557: return MSG_NG;
2558: }
2559: if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0))
2560: {
2561: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2562: zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas);
2563: return MSG_NG;
2564: }
2565: lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen);
2566: length -= lsalen;
2567: }
2568: counted_lsas++;
2569: }
2570:
2571: if (declared_num_lsas && counted_lsas != declared_num_lsas)
2572: {
2573: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2574: zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
2575: __func__, declared_num_lsas, counted_lsas);
2576: return MSG_NG;
2577: }
2578: return MSG_OK;
2579: }
2580:
2581: /* Verify a complete OSPF packet for proper sizing/alignment. */
2582: static unsigned
2583: ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire)
2584: {
2585: u_int16_t bytesdeclared, bytesauth;
2586: unsigned ret;
2587: struct ospf_ls_update * lsupd;
2588:
2589: /* Length, 1st approximation. */
2590: if (bytesonwire < OSPF_HEADER_SIZE)
2591: {
2592: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2593: zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
2594: return MSG_NG;
2595: }
2596: /* Now it is safe to access header fields. Performing length check, allow
2597: * for possible extra bytes of crypto auth/padding, which are not counted
2598: * in the OSPF header "length" field. */
2599: if (oh->version != OSPF_VERSION)
2600: {
2601: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2602: zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
2603: return MSG_NG;
2604: }
2605: bytesdeclared = ntohs (oh->length);
2606: if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2607: bytesauth = 0;
2608: else
2609: {
2610: if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE)
2611: {
2612: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2613: zlog_debug ("%s: unsupported crypto auth length (%u B)",
2614: __func__, oh->u.crypt.auth_data_len);
2615: return MSG_NG;
2616: }
2617: bytesauth = OSPF_AUTH_MD5_SIZE;
2618: }
2619: if (bytesdeclared + bytesauth > bytesonwire)
2620: {
2621: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2622: zlog_debug ("%s: packet length error (%u real, %u+%u declared)",
2623: __func__, bytesonwire, bytesdeclared, bytesauth);
2624: return MSG_NG;
2625: }
2626: /* Length, 2nd approximation. The type-specific constraint is checked
2627: against declared length, not amount of bytes on wire. */
2628: if
2629: (
2630: oh->type >= OSPF_MSG_HELLO &&
2631: oh->type <= OSPF_MSG_LS_ACK &&
2632: bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]
2633: )
2634: {
2635: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2636: zlog_debug ("%s: undersized (%u B) %s packet", __func__,
2637: bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type));
2638: return MSG_NG;
2639: }
2640: switch (oh->type)
2641: {
2642: case OSPF_MSG_HELLO:
2643: /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed
2644: by N>=0 router-IDs. */
2645: ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK;
2646: break;
2647: case OSPF_MSG_DB_DESC:
2648: /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed
2649: by N>=0 header-only LSAs. */
2650: ret = ospf_lsaseq_examin
2651: (
2652: (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE),
2653: bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE,
2654: 1, /* header-only LSAs */
2655: 0
2656: );
2657: break;
2658: case OSPF_MSG_LS_REQ:
2659: /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */
2660: ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) %
2661: OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK;
2662: break;
2663: case OSPF_MSG_LS_UPD:
2664: /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed
2665: by N>=0 full LSAs (with N declared beforehand). */
2666: lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE);
2667: ret = ospf_lsaseq_examin
2668: (
2669: (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE),
2670: bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE,
2671: 0, /* full LSAs */
2672: ntohl (lsupd->num_lsas) /* 32 bits */
2673: );
2674: break;
2675: case OSPF_MSG_LS_ACK:
2676: /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */
2677: ret = ospf_lsaseq_examin
2678: (
2679: (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE),
2680: bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE,
2681: 1, /* header-only LSAs */
2682: 0
2683: );
2684: break;
2685: default:
2686: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2687: zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type);
2688: return MSG_NG;
1.1 misho 2689: }
1.1.1.2 misho 2690: if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV))
2691: zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type));
2692: return ret;
2693: }
1.1 misho 2694:
1.1.1.2 misho 2695: /* OSPF Header verification. */
2696: static int
2697: ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2698: struct ip *iph, struct ospf_header *ospfh)
2699: {
1.1 misho 2700: /* Check Area ID. */
2701: if (!ospf_check_area_id (oi, ospfh))
2702: {
2703: zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2704: IF_NAME (oi), inet_ntoa (ospfh->area_id));
2705: return -1;
2706: }
2707:
2708: /* Check network mask, Silently discarded. */
2709: if (! ospf_check_network_mask (oi, iph->ip_src))
2710: {
2711: zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2712: IF_NAME (oi), inet_ntoa (iph->ip_src));
2713: return -1;
2714: }
2715:
1.1.1.2 misho 2716: /* Check authentication. The function handles logging actions, where required. */
2717: if (! ospf_check_auth (oi, ospfh))
2718: return -1;
1.1 misho 2719:
2720: return 0;
2721: }
2722:
2723: /* Starting point of packet process function. */
2724: int
2725: ospf_read (struct thread *thread)
2726: {
2727: int ret;
2728: struct stream *ibuf;
2729: struct ospf *ospf;
2730: struct ospf_interface *oi;
2731: struct ip *iph;
2732: struct ospf_header *ospfh;
2733: u_int16_t length;
2734: struct interface *ifp;
2735:
2736: /* first of all get interface pointer. */
2737: ospf = THREAD_ARG (thread);
2738:
2739: /* prepare for next packet. */
2740: ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
2741:
2742: stream_reset(ospf->ibuf);
2743: if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
2744: return -1;
1.1.1.2 misho 2745: /* This raw packet is known to be at least as big as its IP header. */
1.1 misho 2746:
2747: /* Note that there should not be alignment problems with this assignment
2748: because this is at the beginning of the stream data buffer. */
2749: iph = (struct ip *) STREAM_DATA (ibuf);
2750: /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
2751:
2752: if (ifp == NULL)
2753: /* Handle cases where the platform does not support retrieving the ifindex,
2754: and also platforms (such as Solaris 8) that claim to support ifindex
2755: retrieval but do not. */
2756: ifp = if_lookup_address (iph->ip_src);
2757:
2758: if (ifp == NULL)
2759: return 0;
2760:
2761: /* IP Header dump. */
2762: if (IS_DEBUG_OSPF_PACKET(0, RECV))
2763: ospf_ip_header_dump (iph);
2764:
2765: /* Self-originated packet should be discarded silently. */
2766: if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
2767: {
2768: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2769: {
2770: zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
2771: inet_ntoa (iph->ip_src));
2772: }
2773: return 0;
2774: }
2775:
2776: /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2777: by ospf_recv_packet() to be correct). */
2778: stream_forward_getp (ibuf, iph->ip_hl * 4);
2779:
1.1.1.2 misho 2780: ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2781: if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf)))
1.1 misho 2782: return -1;
2783: /* Now it is safe to access all fields of OSPF packet header. */
2784:
2785: /* associate packet with ospf interface */
2786: oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
2787:
2788: /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2789: after the passive/backbone/other checks below are passed. These checks
2790: in turn access the fields of unverified "ospfh" structure for their own
2791: purposes and must remain very accurate in doing this. */
2792:
2793: /* If incoming interface is passive one, ignore it. */
2794: if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2795: {
2796: char buf[3][INET_ADDRSTRLEN];
2797:
2798: if (IS_DEBUG_OSPF_EVENT)
2799: zlog_debug ("ignoring packet from router %s sent to %s, "
2800: "received on a passive interface, %s",
2801: inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2802: inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2803: inet_ntop(AF_INET, &oi->address->u.prefix4,
2804: buf[2], sizeof(buf[2])));
2805:
2806: if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2807: {
2808: /* Try to fix multicast membership.
2809: * Some OS:es may have problems in this area,
2810: * make sure it is removed.
2811: */
2812: OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2813: ospf_if_set_multicast(oi);
2814: }
2815: return 0;
2816: }
2817:
2818:
2819: /* if no local ospf_interface,
2820: * or header area is backbone but ospf_interface is not
2821: * check for VLINK interface
2822: */
2823: if ( (oi == NULL) ||
2824: (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2825: && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2826: )
2827: {
2828: if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2829: {
2830: if (IS_DEBUG_OSPF_EVENT)
2831: zlog_debug ("Packet from [%s] received on link %s"
2832: " but no ospf_interface",
2833: inet_ntoa (iph->ip_src), ifp->name);
2834: return 0;
2835: }
2836: }
2837:
2838: /* else it must be a local ospf interface, check it was received on
2839: * correct link
2840: */
2841: else if (oi->ifp != ifp)
2842: {
2843: if (IS_DEBUG_OSPF_EVENT)
2844: zlog_warn ("Packet from [%s] received on wrong link %s",
2845: inet_ntoa (iph->ip_src), ifp->name);
2846: return 0;
2847: }
2848: else if (oi->state == ISM_Down)
2849: {
2850: char buf[2][INET_ADDRSTRLEN];
2851: zlog_warn ("Ignoring packet from %s to %s received on interface that is "
2852: "down [%s]; interface flags are %s",
2853: inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2854: inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2855: ifp->name, if_flag_dump(ifp->flags));
2856: /* Fix multicast memberships? */
2857: if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2858: OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2859: else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2860: OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
2861: if (oi->multicast_memberships)
2862: ospf_if_set_multicast(oi);
2863: return 0;
2864: }
2865:
2866: /*
2867: * If the received packet is destined for AllDRouters, the packet
2868: * should be accepted only if the received ospf interface state is
2869: * either DR or Backup -- endo.
2870: */
2871: if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2872: && (oi->state != ISM_DR && oi->state != ISM_Backup))
2873: {
2874: zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2875: inet_ntoa (iph->ip_src), IF_NAME (oi),
2876: LOOKUP (ospf_ism_state_msg, oi->state));
2877: /* Try to fix multicast membership. */
2878: SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2879: ospf_if_set_multicast(oi);
2880: return 0;
2881: }
2882:
2883: /* Verify more OSPF header fields. */
2884: ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2885: if (ret < 0)
2886: {
2887: if (IS_DEBUG_OSPF_PACKET (0, RECV))
2888: zlog_debug ("ospf_read[%s]: Header check failed, "
2889: "dropping.",
2890: inet_ntoa (iph->ip_src));
2891: return ret;
2892: }
2893:
2894: /* Show debug receiving packet. */
2895: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2896: {
2897: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2898: {
2899: zlog_debug ("-----------------------------------------------------");
2900: ospf_packet_dump (ibuf);
2901: }
2902:
2903: zlog_debug ("%s received from [%s] via [%s]",
1.1.1.2 misho 2904: LOOKUP (ospf_packet_type_str, ospfh->type),
1.1 misho 2905: inet_ntoa (ospfh->router_id), IF_NAME (oi));
2906: zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2907: zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
2908:
2909: if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2910: zlog_debug ("-----------------------------------------------------");
2911: }
2912:
2913: stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
2914:
2915: /* Adjust size to message length. */
2916: length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2917:
2918: /* Read rest of the packet and call each sort of packet routine. */
2919: switch (ospfh->type)
2920: {
2921: case OSPF_MSG_HELLO:
2922: ospf_hello (iph, ospfh, ibuf, oi, length);
2923: break;
2924: case OSPF_MSG_DB_DESC:
2925: ospf_db_desc (iph, ospfh, ibuf, oi, length);
2926: break;
2927: case OSPF_MSG_LS_REQ:
2928: ospf_ls_req (iph, ospfh, ibuf, oi, length);
2929: break;
2930: case OSPF_MSG_LS_UPD:
2931: ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2932: break;
2933: case OSPF_MSG_LS_ACK:
2934: ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2935: break;
2936: default:
2937: zlog (NULL, LOG_WARNING,
2938: "interface %s: OSPF packet header type %d is illegal",
2939: IF_NAME (oi), ospfh->type);
2940: break;
2941: }
2942:
2943: return 0;
2944: }
2945:
2946: /* Make OSPF header. */
2947: static void
2948: ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2949: {
2950: struct ospf_header *ospfh;
2951:
2952: ospfh = (struct ospf_header *) STREAM_DATA (s);
2953:
2954: ospfh->version = (u_char) OSPF_VERSION;
2955: ospfh->type = (u_char) type;
2956:
2957: ospfh->router_id = oi->ospf->router_id;
2958:
2959: ospfh->checksum = 0;
2960: ospfh->area_id = oi->area->area_id;
2961: ospfh->auth_type = htons (ospf_auth_type (oi));
2962:
2963: memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2964:
2965: stream_forward_endp (s, OSPF_HEADER_SIZE);
2966: }
2967:
2968: /* Make Authentication Data. */
2969: static int
2970: ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2971: {
2972: struct crypt_key *ck;
2973:
2974: switch (ospf_auth_type (oi))
2975: {
2976: case OSPF_AUTH_NULL:
2977: /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2978: break;
2979: case OSPF_AUTH_SIMPLE:
2980: memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2981: OSPF_AUTH_SIMPLE_SIZE);
2982: break;
2983: case OSPF_AUTH_CRYPTOGRAPHIC:
2984: /* If key is not set, then set 0. */
2985: if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2986: {
2987: ospfh->u.crypt.zero = 0;
2988: ospfh->u.crypt.key_id = 0;
2989: ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2990: }
2991: else
2992: {
2993: ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
2994: ospfh->u.crypt.zero = 0;
2995: ospfh->u.crypt.key_id = ck->key_id;
2996: ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2997: }
2998: /* note: the seq is done in ospf_make_md5_digest() */
2999: break;
3000: default:
3001: /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
3002: break;
3003: }
3004:
3005: return 0;
3006: }
3007:
3008: /* Fill rest of OSPF header. */
3009: static void
3010: ospf_fill_header (struct ospf_interface *oi,
3011: struct stream *s, u_int16_t length)
3012: {
3013: struct ospf_header *ospfh;
3014:
3015: ospfh = (struct ospf_header *) STREAM_DATA (s);
3016:
3017: /* Fill length. */
3018: ospfh->length = htons (length);
3019:
3020: /* Calculate checksum. */
3021: if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
3022: ospfh->checksum = in_cksum (ospfh, length);
3023: else
3024: ospfh->checksum = 0;
3025:
3026: /* Add Authentication Data. */
3027: ospf_make_auth (oi, ospfh);
3028: }
3029:
3030: static int
3031: ospf_make_hello (struct ospf_interface *oi, struct stream *s)
3032: {
3033: struct ospf_neighbor *nbr;
3034: struct route_node *rn;
3035: u_int16_t length = OSPF_HELLO_MIN_SIZE;
3036: struct in_addr mask;
3037: unsigned long p;
3038: int flag = 0;
3039:
3040: /* Set netmask of interface. */
3041: if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
3042: oi->type != OSPF_IFTYPE_VIRTUALLINK)
3043: masklen2ip (oi->address->prefixlen, &mask);
3044: else
3045: memset ((char *) &mask, 0, sizeof (struct in_addr));
3046: stream_put_ipv4 (s, mask.s_addr);
3047:
3048: /* Set Hello Interval. */
3049: if (OSPF_IF_PARAM (oi, fast_hello) == 0)
3050: stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
3051: else
3052: stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
3053:
3054: if (IS_DEBUG_OSPF_EVENT)
3055: zlog_debug ("make_hello: options: %x, int: %s",
3056: OPTIONS(oi), IF_NAME (oi));
3057:
3058: /* Set Options. */
3059: stream_putc (s, OPTIONS (oi));
3060:
3061: /* Set Router Priority. */
3062: stream_putc (s, PRIORITY (oi));
3063:
3064: /* Set Router Dead Interval. */
3065: stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
3066:
3067: /* Set Designated Router. */
3068: stream_put_ipv4 (s, DR (oi).s_addr);
3069:
3070: p = stream_get_endp (s);
3071:
3072: /* Set Backup Designated Router. */
3073: stream_put_ipv4 (s, BDR (oi).s_addr);
3074:
3075: /* Add neighbor seen. */
3076: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3077: if ((nbr = rn->info))
3078: if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
3079: if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
3080: if (nbr->state != NSM_Down) /* This is myself for DR election. */
3081: if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
3082: {
3083: /* Check neighbor is sane? */
3084: if (nbr->d_router.s_addr != 0
3085: && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
3086: && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
3087: flag = 1;
3088:
3089: stream_put_ipv4 (s, nbr->router_id.s_addr);
3090: length += 4;
3091: }
3092:
3093: /* Let neighbor generate BackupSeen. */
3094: if (flag == 1)
3095: stream_putl_at (s, p, 0); /* ipv4 address, normally */
3096:
3097: return length;
3098: }
3099:
3100: static int
3101: ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
3102: struct stream *s)
3103: {
3104: struct ospf_lsa *lsa;
3105: u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
3106: u_char options;
3107: unsigned long pp;
3108: int i;
3109: struct ospf_lsdb *lsdb;
3110:
3111: /* Set Interface MTU. */
3112: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3113: stream_putw (s, 0);
3114: else
3115: stream_putw (s, oi->ifp->mtu);
3116:
3117: /* Set Options. */
3118: options = OPTIONS (oi);
3119: #ifdef HAVE_OPAQUE_LSA
3120: if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
3121: {
3122: if (IS_SET_DD_I (nbr->dd_flags)
3123: || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
3124: /*
3125: * Set O-bit in the outgoing DD packet for capablity negotiation,
3126: * if one of following case is applicable.
3127: *
3128: * 1) WaitTimer expiration event triggered the neighbor state to
3129: * change to Exstart, but no (valid) DD packet has received
3130: * from the neighbor yet.
3131: *
3132: * 2) At least one DD packet with O-bit on has received from the
3133: * neighbor.
3134: */
3135: SET_FLAG (options, OSPF_OPTION_O);
3136: }
3137: #endif /* HAVE_OPAQUE_LSA */
3138: stream_putc (s, options);
3139:
3140: /* DD flags */
3141: pp = stream_get_endp (s);
3142: stream_putc (s, nbr->dd_flags);
3143:
3144: /* Set DD Sequence Number. */
3145: stream_putl (s, nbr->dd_seqnum);
3146:
3147: /* shortcut unneeded walk of (empty) summary LSDBs */
3148: if (ospf_db_summary_isempty (nbr))
3149: goto empty;
3150:
3151: /* Describe LSA Header from Database Summary List. */
3152: lsdb = &nbr->db_sum;
3153:
3154: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3155: {
3156: struct route_table *table = lsdb->type[i].db;
3157: struct route_node *rn;
3158:
3159: for (rn = route_top (table); rn; rn = route_next (rn))
3160: if ((lsa = rn->info) != NULL)
3161: {
3162: #ifdef HAVE_OPAQUE_LSA
3163: if (IS_OPAQUE_LSA (lsa->data->type)
3164: && (! CHECK_FLAG (options, OSPF_OPTION_O)))
3165: {
3166: /* Suppress advertising opaque-informations. */
3167: /* Remove LSA from DB summary list. */
3168: ospf_lsdb_delete (lsdb, lsa);
3169: continue;
3170: }
3171: #endif /* HAVE_OPAQUE_LSA */
3172:
3173: if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
3174: {
3175: struct lsa_header *lsah;
3176: u_int16_t ls_age;
3177:
3178: /* DD packet overflows interface MTU. */
3179: if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
3180: break;
3181:
3182: /* Keep pointer to LS age. */
3183: lsah = (struct lsa_header *) (STREAM_DATA (s) +
3184: stream_get_endp (s));
3185:
3186: /* Proceed stream pointer. */
3187: stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3188: length += OSPF_LSA_HEADER_SIZE;
3189:
3190: /* Set LS age. */
3191: ls_age = LS_AGE (lsa);
3192: lsah->ls_age = htons (ls_age);
3193:
3194: }
3195:
3196: /* Remove LSA from DB summary list. */
3197: ospf_lsdb_delete (lsdb, lsa);
3198: }
3199: }
3200:
3201: /* Update 'More' bit */
3202: if (ospf_db_summary_isempty (nbr))
3203: {
3204: empty:
3205: if (nbr->state >= NSM_Exchange)
3206: {
3207: UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
3208: /* Rewrite DD flags */
3209: stream_putc_at (s, pp, nbr->dd_flags);
3210: }
3211: else
3212: {
3213: assert (IS_SET_DD_M(nbr->dd_flags));
3214: }
3215: }
3216: return length;
3217: }
3218:
3219: static int
3220: ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
3221: unsigned long delta, struct ospf_neighbor *nbr,
3222: struct ospf_lsa *lsa)
3223: {
3224: struct ospf_interface *oi;
3225:
3226: oi = nbr->oi;
3227:
3228: /* LS Request packet overflows interface MTU. */
3229: if (*length + delta > ospf_packet_max(oi))
3230: return 0;
3231:
3232: stream_putl (s, lsa->data->type);
3233: stream_put_ipv4 (s, lsa->data->id.s_addr);
3234: stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
3235:
3236: ospf_lsa_unlock (&nbr->ls_req_last);
3237: nbr->ls_req_last = ospf_lsa_lock (lsa);
3238:
3239: *length += 12;
3240: return 1;
3241: }
3242:
3243: static int
3244: ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
3245: {
3246: struct ospf_lsa *lsa;
3247: u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
3248: unsigned long delta = stream_get_endp(s)+12;
3249: struct route_table *table;
3250: struct route_node *rn;
3251: int i;
3252: struct ospf_lsdb *lsdb;
3253:
3254: lsdb = &nbr->ls_req;
3255:
3256: for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
3257: {
3258: table = lsdb->type[i].db;
3259: for (rn = route_top (table); rn; rn = route_next (rn))
3260: if ((lsa = (rn->info)) != NULL)
3261: if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
3262: {
3263: route_unlock_node (rn);
3264: break;
3265: }
3266: }
3267: return length;
3268: }
3269:
3270: static int
3271: ls_age_increment (struct ospf_lsa *lsa, int delay)
3272: {
3273: int age;
3274:
3275: age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
3276:
3277: return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
3278: }
3279:
3280: static int
3281: ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
3282: {
3283: struct ospf_lsa *lsa;
3284: struct listnode *node;
3285: u_int16_t length = 0;
3286: unsigned int size_noauth;
3287: unsigned long delta = stream_get_endp (s);
3288: unsigned long pp;
3289: int count = 0;
3290:
3291: if (IS_DEBUG_OSPF_EVENT)
3292: zlog_debug ("ospf_make_ls_upd: Start");
3293:
3294: pp = stream_get_endp (s);
3295: stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
3296: length += OSPF_LS_UPD_MIN_SIZE;
3297:
3298: /* Calculate amount of packet usable for data. */
3299: size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
3300:
3301: while ((node = listhead (update)) != NULL)
3302: {
3303: struct lsa_header *lsah;
3304: u_int16_t ls_age;
3305:
3306: if (IS_DEBUG_OSPF_EVENT)
3307: zlog_debug ("ospf_make_ls_upd: List Iteration");
3308:
3309: lsa = listgetdata (node);
3310:
3311: assert (lsa->data);
3312:
3313: /* Will it fit? */
3314: if (length + delta + ntohs (lsa->data->length) > size_noauth)
3315: break;
3316:
3317: /* Keep pointer to LS age. */
3318: lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
3319:
3320: /* Put LSA to Link State Request. */
3321: stream_put (s, lsa->data, ntohs (lsa->data->length));
3322:
3323: /* Set LS age. */
3324: /* each hop must increment an lsa_age by transmit_delay
3325: of OSPF interface */
3326: ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
3327: lsah->ls_age = htons (ls_age);
3328:
3329: length += ntohs (lsa->data->length);
3330: count++;
3331:
3332: list_delete_node (update, node);
3333: ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
3334: }
3335:
3336: /* Now set #LSAs. */
3337: stream_putl_at (s, pp, count);
3338:
3339: if (IS_DEBUG_OSPF_EVENT)
3340: zlog_debug ("ospf_make_ls_upd: Stop");
3341: return length;
3342: }
3343:
3344: static int
3345: ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
3346: {
3347: struct listnode *node, *nnode;
3348: u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
3349: unsigned long delta = stream_get_endp(s) + 24;
3350: struct ospf_lsa *lsa;
3351:
3352: for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
3353: {
3354: assert (lsa);
3355:
3356: if (length + delta > ospf_packet_max (oi))
3357: break;
3358:
3359: stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
3360: length += OSPF_LSA_HEADER_SIZE;
3361:
3362: listnode_delete (ack, lsa);
3363: ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
3364: }
3365:
3366: return length;
3367: }
3368:
3369: static void
3370: ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
3371: {
3372: struct ospf_packet *op;
3373: u_int16_t length = OSPF_HEADER_SIZE;
3374:
3375: op = ospf_packet_new (oi->ifp->mtu);
3376:
3377: /* Prepare OSPF common header. */
3378: ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3379:
3380: /* Prepare OSPF Hello body. */
3381: length += ospf_make_hello (oi, op->s);
3382:
3383: /* Fill OSPF header. */
3384: ospf_fill_header (oi, op->s, length);
3385:
3386: /* Set packet length. */
3387: op->length = length;
3388:
3389: op->dst.s_addr = addr;
3390:
3391: /* Add packet to the top of the interface output queue, so that they
3392: * can't get delayed by things like long queues of LS Update packets
3393: */
3394: ospf_packet_add_top (oi, op);
3395:
3396: /* Hook thread to write packet. */
3397: OSPF_ISM_WRITE_ON (oi->ospf);
3398: }
3399:
3400: static void
3401: ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3402: {
3403: struct ospf_interface *oi;
3404:
3405: oi = nbr_nbma->oi;
3406: assert(oi);
3407:
3408: /* If this is passive interface, do not send OSPF Hello. */
3409: if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
3410: return;
3411:
3412: if (oi->type != OSPF_IFTYPE_NBMA)
3413: return;
3414:
3415: if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3416: return;
3417:
3418: if (PRIORITY(oi) == 0)
3419: return;
3420:
3421: if (nbr_nbma->priority == 0
3422: && oi->state != ISM_DR && oi->state != ISM_Backup)
3423: return;
3424:
3425: ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
3426: }
3427:
3428: int
3429: ospf_poll_timer (struct thread *thread)
3430: {
3431: struct ospf_nbr_nbma *nbr_nbma;
3432:
3433: nbr_nbma = THREAD_ARG (thread);
3434: nbr_nbma->t_poll = NULL;
3435:
3436: if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
3437: zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
3438: IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3439:
3440: ospf_poll_send (nbr_nbma);
3441:
3442: if (nbr_nbma->v_poll > 0)
3443: OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3444: nbr_nbma->v_poll);
3445:
3446: return 0;
3447: }
3448:
3449:
3450: int
3451: ospf_hello_reply_timer (struct thread *thread)
3452: {
3453: struct ospf_neighbor *nbr;
3454:
3455: nbr = THREAD_ARG (thread);
3456: nbr->t_hello_reply = NULL;
3457:
3458: assert (nbr->oi);
3459:
3460: if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
3461: zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
3462: IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3463:
3464: ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
3465:
3466: return 0;
3467: }
3468:
3469: /* Send OSPF Hello. */
3470: void
3471: ospf_hello_send (struct ospf_interface *oi)
3472: {
3473: /* If this is passive interface, do not send OSPF Hello. */
3474: if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
3475: return;
3476:
3477: if (oi->type == OSPF_IFTYPE_NBMA)
3478: {
3479: struct ospf_neighbor *nbr;
3480: struct route_node *rn;
3481:
3482: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3483: if ((nbr = rn->info))
3484: if (nbr != oi->nbr_self)
3485: if (nbr->state != NSM_Down)
3486: {
3487: /* RFC 2328 Section 9.5.1
3488: If the router is not eligible to become Designated Router,
3489: it must periodically send Hello Packets to both the
3490: Designated Router and the Backup Designated Router (if they
3491: exist). */
3492: if (PRIORITY(oi) == 0 &&
3493: IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3494: IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3495: continue;
3496:
3497: /* If the router is eligible to become Designated Router, it
3498: must periodically send Hello Packets to all neighbors that
3499: are also eligible. In addition, if the router is itself the
3500: Designated Router or Backup Designated Router, it must also
3501: send periodic Hello Packets to all other neighbors. */
3502:
3503: if (nbr->priority == 0 && oi->state == ISM_DROther)
3504: continue;
3505: /* if oi->state == Waiting, send hello to all neighbors */
3506: ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
3507: }
3508: }
3509: else
3510: {
3511: /* Decide destination address. */
3512: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3513: ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
3514: else
3515: ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
3516: }
3517: }
3518:
3519: /* Send OSPF Database Description. */
3520: void
3521: ospf_db_desc_send (struct ospf_neighbor *nbr)
3522: {
3523: struct ospf_interface *oi;
3524: struct ospf_packet *op;
3525: u_int16_t length = OSPF_HEADER_SIZE;
3526:
3527: oi = nbr->oi;
3528: op = ospf_packet_new (oi->ifp->mtu);
3529:
3530: /* Prepare OSPF common header. */
3531: ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3532:
3533: /* Prepare OSPF Database Description body. */
3534: length += ospf_make_db_desc (oi, nbr, op->s);
3535:
3536: /* Fill OSPF header. */
3537: ospf_fill_header (oi, op->s, length);
3538:
3539: /* Set packet length. */
3540: op->length = length;
3541:
3542: /* Decide destination address. */
3543: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3544: op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3545: else
3546: op->dst = nbr->address.u.prefix4;
3547:
3548: /* Add packet to the interface output queue. */
3549: ospf_packet_add (oi, op);
3550:
3551: /* Hook thread to write packet. */
3552: OSPF_ISM_WRITE_ON (oi->ospf);
3553:
3554: /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3555: if (nbr->last_send)
3556: ospf_packet_free (nbr->last_send);
3557: nbr->last_send = ospf_packet_dup (op);
3558: quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
3559: }
3560:
3561: /* Re-send Database Description. */
3562: void
3563: ospf_db_desc_resend (struct ospf_neighbor *nbr)
3564: {
3565: struct ospf_interface *oi;
3566:
3567: oi = nbr->oi;
3568:
3569: /* Add packet to the interface output queue. */
3570: ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3571:
3572: /* Hook thread to write packet. */
3573: OSPF_ISM_WRITE_ON (oi->ospf);
3574: }
3575:
3576: /* Send Link State Request. */
3577: void
3578: ospf_ls_req_send (struct ospf_neighbor *nbr)
3579: {
3580: struct ospf_interface *oi;
3581: struct ospf_packet *op;
3582: u_int16_t length = OSPF_HEADER_SIZE;
3583:
3584: oi = nbr->oi;
3585: op = ospf_packet_new (oi->ifp->mtu);
3586:
3587: /* Prepare OSPF common header. */
3588: ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3589:
3590: /* Prepare OSPF Link State Request body. */
3591: length += ospf_make_ls_req (nbr, op->s);
3592: if (length == OSPF_HEADER_SIZE)
3593: {
3594: ospf_packet_free (op);
3595: return;
3596: }
3597:
3598: /* Fill OSPF header. */
3599: ospf_fill_header (oi, op->s, length);
3600:
3601: /* Set packet length. */
3602: op->length = length;
3603:
3604: /* Decide destination address. */
3605: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3606: op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3607: else
3608: op->dst = nbr->address.u.prefix4;
3609:
3610: /* Add packet to the interface output queue. */
3611: ospf_packet_add (oi, op);
3612:
3613: /* Hook thread to write packet. */
3614: OSPF_ISM_WRITE_ON (oi->ospf);
3615:
3616: /* Add Link State Request Retransmission Timer. */
3617: OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3618: }
3619:
3620: /* Send Link State Update with an LSA. */
3621: void
3622: ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3623: int flag)
3624: {
3625: struct list *update;
3626:
3627: update = list_new ();
3628:
3629: listnode_add (update, lsa);
3630: ospf_ls_upd_send (nbr, update, flag);
3631:
3632: list_delete (update);
3633: }
3634:
3635: /* Determine size for packet. Must be at least big enough to accomodate next
3636: * LSA on list, which may be bigger than MTU size.
3637: *
3638: * Return pointer to new ospf_packet
3639: * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3640: * on packet sizes (in which case offending LSA is deleted from update list)
3641: */
3642: static struct ospf_packet *
3643: ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3644: {
3645: struct ospf_lsa *lsa;
3646: struct listnode *ln;
3647: size_t size;
3648: static char warned = 0;
3649:
3650: lsa = listgetdata((ln = listhead (update)));
3651: assert (lsa->data);
3652:
3653: if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3654: > ospf_packet_max (oi))
3655: {
3656: if (!warned)
3657: {
3658: zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3659: "will need to fragment. Not optimal. Try divide up"
3660: " your network with areas. Use 'debug ospf packet send'"
3661: " to see details, or look at 'show ip ospf database ..'");
3662: warned = 1;
3663: }
3664:
3665: if (IS_DEBUG_OSPF_PACKET (0, SEND))
3666: zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3667: " %d bytes originated by %s, will be fragmented!",
3668: inet_ntoa (lsa->data->id),
3669: ntohs (lsa->data->length),
3670: inet_ntoa (lsa->data->adv_router));
3671:
3672: /*
3673: * Allocate just enough to fit this LSA only, to avoid including other
3674: * LSAs in fragmented LSA Updates.
3675: */
3676: size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3677: + OSPF_LS_UPD_MIN_SIZE;
3678: }
3679: else
3680: size = oi->ifp->mtu;
3681:
3682: if (size > OSPF_MAX_PACKET_SIZE)
3683: {
3684: zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3685: " %d bytes, packet size %ld, dropping it completely."
3686: " OSPF routing is broken!",
3687: inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
3688: (long int) size);
3689: list_delete_node (update, ln);
3690: return NULL;
3691: }
3692:
3693: /* IP header is built up separately by ospf_write(). This means, that we must
3694: * reduce the "affordable" size just calculated by length of an IP header.
3695: * This makes sure, that even if we manage to fill the payload with LSA data
3696: * completely, the final packet (our data plus IP header) still fits into
3697: * outgoing interface MTU. This correction isn't really meaningful for an
3698: * oversized LSA, but for consistency the correction is done for both cases.
3699: *
3700: * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3701: */
3702: return ospf_packet_new (size - sizeof (struct ip));
3703: }
3704:
3705: static void
3706: ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
3707: struct in_addr addr)
3708: {
3709: struct ospf_packet *op;
3710: u_int16_t length = OSPF_HEADER_SIZE;
3711:
3712: if (IS_DEBUG_OSPF_EVENT)
3713: zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
3714:
3715: op = ospf_ls_upd_packet_new (update, oi);
3716:
3717: /* Prepare OSPF common header. */
3718: ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3719:
3720: /* Prepare OSPF Link State Update body.
3721: * Includes Type-7 translation.
3722: */
3723: length += ospf_make_ls_upd (oi, update, op->s);
3724:
3725: /* Fill OSPF header. */
3726: ospf_fill_header (oi, op->s, length);
3727:
3728: /* Set packet length. */
3729: op->length = length;
3730:
3731: /* Decide destination address. */
3732: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3733: op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3734: else
3735: op->dst.s_addr = addr.s_addr;
3736:
3737: /* Add packet to the interface output queue. */
3738: ospf_packet_add (oi, op);
3739:
3740: /* Hook thread to write packet. */
3741: OSPF_ISM_WRITE_ON (oi->ospf);
3742: }
3743:
3744: static int
3745: ospf_ls_upd_send_queue_event (struct thread *thread)
3746: {
3747: struct ospf_interface *oi = THREAD_ARG(thread);
3748: struct route_node *rn;
3749: struct route_node *rnext;
3750: struct list *update;
3751: char again = 0;
3752:
3753: oi->t_ls_upd_event = NULL;
3754:
3755: if (IS_DEBUG_OSPF_EVENT)
3756: zlog_debug ("ospf_ls_upd_send_queue start");
3757:
3758: for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
3759: {
3760: rnext = route_next (rn);
3761:
3762: if (rn->info == NULL)
3763: continue;
3764:
3765: update = (struct list *)rn->info;
3766:
3767: ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
3768:
3769: /* list might not be empty. */
3770: if (listcount(update) == 0)
3771: {
3772: list_delete (rn->info);
3773: rn->info = NULL;
3774: route_unlock_node (rn);
3775: }
3776: else
3777: again = 1;
3778: }
3779:
3780: if (again != 0)
3781: {
3782: if (IS_DEBUG_OSPF_EVENT)
3783: zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
3784: " %d nodes to try again, raising new event", again);
3785: oi->t_ls_upd_event =
3786: thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3787: }
3788:
3789: if (IS_DEBUG_OSPF_EVENT)
3790: zlog_debug ("ospf_ls_upd_send_queue stop");
3791:
3792: return 0;
3793: }
3794:
3795: void
3796: ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
3797: {
3798: struct ospf_interface *oi;
3799: struct ospf_lsa *lsa;
3800: struct prefix_ipv4 p;
3801: struct route_node *rn;
3802: struct listnode *node;
3803:
3804: oi = nbr->oi;
3805:
3806: p.family = AF_INET;
3807: p.prefixlen = IPV4_MAX_BITLEN;
3808:
3809: /* Decide destination address. */
3810: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3811: p.prefix = oi->vl_data->peer_addr;
3812: else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3813: p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3814: else if (flag == OSPF_SEND_PACKET_DIRECT)
3815: p.prefix = nbr->address.u.prefix4;
3816: else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3817: p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3818: else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3819: p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3820: else
3821: p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3822:
3823: if (oi->type == OSPF_IFTYPE_NBMA)
3824: {
3825: if (flag == OSPF_SEND_PACKET_INDIRECT)
3826: zlog_warn ("* LS-Update is directly sent on NBMA network.");
3827: if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3828: zlog_warn ("* LS-Update is sent to myself.");
3829: }
3830:
3831: rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3832:
3833: if (rn->info == NULL)
3834: rn->info = list_new ();
3835:
3836: for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3837: listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
3838:
3839: if (oi->t_ls_upd_event == NULL)
3840: oi->t_ls_upd_event =
3841: thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3842: }
3843:
3844: static void
3845: ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3846: struct in_addr dst)
3847: {
3848: struct ospf_packet *op;
3849: u_int16_t length = OSPF_HEADER_SIZE;
3850:
3851: op = ospf_packet_new (oi->ifp->mtu);
3852:
3853: /* Prepare OSPF common header. */
3854: ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3855:
3856: /* Prepare OSPF Link State Acknowledgment body. */
3857: length += ospf_make_ls_ack (oi, ack, op->s);
3858:
3859: /* Fill OSPF header. */
3860: ospf_fill_header (oi, op->s, length);
3861:
3862: /* Set packet length. */
3863: op->length = length;
3864:
3865: /* Set destination IP address. */
3866: op->dst = dst;
3867:
3868: /* Add packet to the interface output queue. */
3869: ospf_packet_add (oi, op);
3870:
3871: /* Hook thread to write packet. */
3872: OSPF_ISM_WRITE_ON (oi->ospf);
3873: }
3874:
3875: static int
3876: ospf_ls_ack_send_event (struct thread *thread)
3877: {
3878: struct ospf_interface *oi = THREAD_ARG (thread);
3879:
3880: oi->t_ls_ack_direct = NULL;
3881:
3882: while (listcount (oi->ls_ack_direct.ls_ack))
3883: ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3884: oi->ls_ack_direct.dst);
3885:
3886: return 0;
3887: }
3888:
3889: void
3890: ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3891: {
3892: struct ospf_interface *oi = nbr->oi;
3893:
3894: if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3895: oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3896:
3897: listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3898:
3899: if (oi->t_ls_ack_direct == NULL)
3900: oi->t_ls_ack_direct =
3901: thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3902: }
3903:
3904: /* Send Link State Acknowledgment delayed. */
3905: void
3906: ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3907: {
3908: struct in_addr dst;
3909:
3910: /* Decide destination address. */
3911: /* RFC2328 Section 13.5 On non-broadcast
3912: networks, delayed Link State Acknowledgment packets must be
3913: unicast separately over each adjacency (i.e., neighbor whose
3914: state is >= Exchange). */
3915: if (oi->type == OSPF_IFTYPE_NBMA)
3916: {
3917: struct ospf_neighbor *nbr;
3918: struct route_node *rn;
3919:
3920: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3921: if ((nbr = rn->info) != NULL)
3922: if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3923: while (listcount (oi->ls_ack))
3924: ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3925: return;
3926: }
3927: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3928: dst.s_addr = oi->vl_data->peer_addr.s_addr;
3929: else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3930: dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3931: else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3932: dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3933: else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3934: dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3935: else
3936: dst.s_addr = htonl (OSPF_ALLDROUTERS);
3937:
3938: while (listcount (oi->ls_ack))
3939: ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3940: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>