xref: /openbsd/usr.sbin/ospf6d/lsupdate.c (revision 09467b48)
1 /*	$OpenBSD: lsupdate.c,v 1.18 2020/07/15 14:47:41 denis Exp $ */
2 
3 /*
4  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2004, 2005, 2007 Esben Norby <norby@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <netinet/ip6.h>
24 #include <netinet/ip_ah.h>
25 #include <arpa/inet.h>
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <siphash.h>
30 
31 #include "ospf6.h"
32 #include "ospf6d.h"
33 #include "log.h"
34 #include "ospfe.h"
35 #include "rde.h"
36 
37 extern struct imsgev		*iev_rde;
38 
39 struct ibuf	*prepare_ls_update(struct iface *, int);
40 int		 add_ls_update(struct ibuf *, struct iface *, void *, u_int16_t,
41 		    u_int16_t);
42 int		 send_ls_update(struct ibuf *, struct iface *, struct in6_addr,
43 		    u_int32_t);
44 
45 void		 ls_retrans_list_insert(struct nbr *, struct lsa_entry *);
46 void		 ls_retrans_list_remove(struct nbr *, struct lsa_entry *);
47 
48 /* link state update packet handling */
49 int
50 lsa_flood(struct iface *iface, struct nbr *originator, struct lsa_hdr *lsa_hdr,
51     void *data)
52 {
53 	struct nbr		*nbr;
54 	struct lsa_entry	*le = NULL;
55 	int			 queued = 0, dont_ack = 0;
56 	int			 r;
57 
58 	LIST_FOREACH(nbr, &iface->nbr_list, entry) {
59 		if (nbr == iface->self)
60 			continue;
61 		if (!(nbr->state & NBR_STA_FLOOD))
62 			continue;
63 
64 		if (iface->state & IF_STA_DROTHER && !queued)
65 			while ((le = ls_retrans_list_get(iface->self, lsa_hdr)))
66 			    ls_retrans_list_free(iface->self, le);
67 
68 		while ((le = ls_retrans_list_get(nbr, lsa_hdr)))
69 			ls_retrans_list_free(nbr, le);
70 
71 		if (!(nbr->state & NBR_STA_FULL) &&
72 		    (le = ls_req_list_get(nbr, lsa_hdr)) != NULL) {
73 			r = lsa_newer(lsa_hdr, le->le_lsa);
74 			if (r > 0) {
75 				/* to flood LSA is newer than requested */
76 				ls_req_list_free(nbr, le);
77 				/* new needs to be flooded */
78 			} else if (r < 0) {
79 				/* to flood LSA is older than requested */
80 				continue;
81 			} else {
82 				/* LSA are equal */
83 				ls_req_list_free(nbr, le);
84 				continue;
85 			}
86 		}
87 
88 		if (nbr == originator) {
89 			dont_ack++;
90 			continue;
91 		}
92 
93 		/* non DR or BDR router keep all lsa in one retrans list */
94 		if (iface->state & IF_STA_DROTHER) {
95 			if (!queued)
96 				ls_retrans_list_add(iface->self, data,
97 				    iface->rxmt_interval, 0);
98 			queued = 1;
99 		} else {
100 			ls_retrans_list_add(nbr, data, iface->rxmt_interval, 0);
101 			queued = 1;
102 		}
103 	}
104 
105 	if (!queued)
106 		return (0);
107 
108 	if (iface == originator->iface && iface->self != originator) {
109 		if (iface->dr == originator || iface->bdr == originator)
110 			return (0);
111 		if (iface->state & IF_STA_BACKUP)
112 			return (0);
113 		dont_ack++;
114 	}
115 
116 	/*
117 	 * initial flood needs to be queued separately, timeout is zero
118 	 * and oneshot has to be set because the retransimssion queues
119 	 * are already loaded.
120 	 */
121 	switch (iface->type) {
122 	case IF_TYPE_POINTOPOINT:
123 	case IF_TYPE_BROADCAST:
124 		ls_retrans_list_add(iface->self, data, 0, 1);
125 		break;
126 	case IF_TYPE_NBMA:
127 	case IF_TYPE_POINTOMULTIPOINT:
128 	case IF_TYPE_VIRTUALLINK:
129 		LIST_FOREACH(nbr, &iface->nbr_list, entry) {
130 			if (nbr == iface->self)
131 				continue;
132 			if (!(nbr->state & NBR_STA_FLOOD))
133 				continue;
134 			if (!TAILQ_EMPTY(&nbr->ls_retrans_list)) {
135 				le = TAILQ_LAST(&nbr->ls_retrans_list,
136 				    lsa_head);
137 				if (lsa_hdr->type != le->le_lsa->type ||
138 				    lsa_hdr->ls_id != le->le_lsa->ls_id ||
139 				    lsa_hdr->adv_rtr != le->le_lsa->adv_rtr)
140 					continue;
141 			}
142 			ls_retrans_list_add(nbr, data, 0, 1);
143 		}
144 		break;
145 	default:
146 		fatalx("lsa_flood: unknown interface type");
147 	}
148 
149 	return (dont_ack == 2);
150 }
151 
152 struct ibuf *
153 prepare_ls_update(struct iface *iface, int bigpkt)
154 {
155 	struct ibuf		*buf;
156 	size_t			 size;
157 
158 	size = bigpkt ? IPV6_MAXPACKET : iface->mtu;
159 	if (size < IPV6_MMTU)
160 		size = IPV6_MMTU;
161 	size -= sizeof(struct ip6_hdr);
162 
163 	/*
164 	 * Reserve space for optional ah or esp encryption.  The
165 	 * algorithm is taken from ah_output and esp_output, the
166 	 * values are the maxima of crypto/xform.c.
167 	 */
168 	size -= max(
169 	    /* base-ah-header replay authsize */
170 	    AH_FLENGTH + sizeof(u_int32_t) + 32,
171 	    /* spi sequence ivlen blocksize pad-length next-header authsize */
172 	    2 * sizeof(u_int32_t) + 16 + 16 + 2 * sizeof(u_int8_t) + 32);
173 
174 	if ((buf = ibuf_open(size)) == NULL)
175 		fatal("prepare_ls_update");
176 
177 	/* OSPF header */
178 	if (gen_ospf_hdr(buf, iface, PACKET_TYPE_LS_UPDATE))
179 		goto fail;
180 
181 	/* reserve space for number of lsa field */
182 	if (ibuf_reserve(buf, sizeof(u_int32_t)) == NULL)
183 		goto fail;
184 
185 	return (buf);
186 fail:
187 	log_warn("prepare_ls_update");
188 	ibuf_free(buf);
189 	return (NULL);
190 }
191 
192 int
193 add_ls_update(struct ibuf *buf, struct iface *iface, void *data, u_int16_t len,
194     u_int16_t older)
195 {
196 	size_t		ageoff;
197 	u_int16_t	age;
198 
199 	if (buf->wpos + len >= buf->max)
200 		return (0);
201 
202 	ageoff = ibuf_size(buf);
203 	if (ibuf_add(buf, data, len)) {
204 		log_warn("add_ls_update");
205 		return (0);
206 	}
207 
208 	/* age LSA before sending it out */
209 	memcpy(&age, data, sizeof(age));
210 	age = ntohs(age);
211 	if ((age += older + iface->transmit_delay) >= MAX_AGE)
212 		age = MAX_AGE;
213 	age = htons(age);
214 	memcpy(ibuf_seek(buf, ageoff, sizeof(age)), &age, sizeof(age));
215 
216 	return (1);
217 }
218 
219 int
220 send_ls_update(struct ibuf *buf, struct iface *iface, struct in6_addr addr,
221     u_int32_t nlsa)
222 {
223 	nlsa = htonl(nlsa);
224 	memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(nlsa)),
225 	    &nlsa, sizeof(nlsa));
226 	/* calculate checksum */
227 	if (upd_ospf_hdr(buf, iface))
228 		goto fail;
229 
230 	if (send_packet(iface, buf, &addr) == -1)
231 		goto fail;
232 
233 	ibuf_free(buf);
234 	return (0);
235 fail:
236 	log_warn("send_ls_update");
237 	ibuf_free(buf);
238 	return (-1);
239 }
240 
241 void
242 recv_ls_update(struct nbr *nbr, char *buf, u_int16_t len)
243 {
244 	struct lsa_hdr		 lsa;
245 	u_int32_t		 nlsa;
246 
247 	if (len < sizeof(nlsa)) {
248 		log_warnx("recv_ls_update: bad packet size, neighbor ID %s",
249 		    inet_ntoa(nbr->id));
250 		return;
251 	}
252 	memcpy(&nlsa, buf, sizeof(nlsa));
253 	nlsa = ntohl(nlsa);
254 	buf += sizeof(nlsa);
255 	len -= sizeof(nlsa);
256 
257 	switch (nbr->state) {
258 	case NBR_STA_DOWN:
259 	case NBR_STA_ATTEMPT:
260 	case NBR_STA_INIT:
261 	case NBR_STA_2_WAY:
262 	case NBR_STA_XSTRT:
263 	case NBR_STA_SNAP:
264 		log_debug("recv_ls_update: packet ignored in state %s, "
265 		    "neighbor ID %s", nbr_state_name(nbr->state),
266 		    inet_ntoa(nbr->id));
267 		break;
268 	case NBR_STA_XCHNG:
269 	case NBR_STA_LOAD:
270 	case NBR_STA_FULL:
271 		for (; nlsa > 0 && len > 0; nlsa--) {
272 			if (len < sizeof(lsa)) {
273 				log_warnx("recv_ls_update: bad packet size, "
274 				    "neighbor ID %s", inet_ntoa(nbr->id));
275 				return;
276 			}
277 			memcpy(&lsa, buf, sizeof(lsa));
278 			if (len < ntohs(lsa.len)) {
279 				log_warnx("recv_ls_update: bad packet size, "
280 				    "neighbor ID %s", inet_ntoa(nbr->id));
281 				return;
282 			}
283 			imsg_compose_event(iev_rde, IMSG_LS_UPD, nbr->peerid, 0,
284 			    -1, buf, ntohs(lsa.len));
285 			buf += ntohs(lsa.len);
286 			len -= ntohs(lsa.len);
287 		}
288 		if (nlsa > 0 || len > 0) {
289 			log_warnx("recv_ls_update: bad packet size, "
290 			    "neighbor ID %s", inet_ntoa(nbr->id));
291 			return;
292 		}
293 		break;
294 	default:
295 		fatalx("recv_ls_update: unknown neighbor state");
296 	}
297 }
298 
299 /* link state retransmit list */
300 void
301 ls_retrans_list_add(struct nbr *nbr, struct lsa_hdr *lsa,
302     unsigned short timeout, unsigned short oneshot)
303 {
304 	struct timeval		 tv;
305 	struct lsa_entry	*le;
306 	struct lsa_ref		*ref;
307 
308 	if ((ref = lsa_cache_get(lsa)) == NULL)
309 		fatalx("King Bula sez: somebody forgot to lsa_cache_add");
310 
311 	if ((le = calloc(1, sizeof(*le))) == NULL)
312 		fatal("ls_retrans_list_add");
313 
314 	le->le_ref = ref;
315 	le->le_when = timeout;
316 	le->le_oneshot = oneshot;
317 
318 	ls_retrans_list_insert(nbr, le);
319 
320 	if (!evtimer_pending(&nbr->ls_retrans_timer, NULL)) {
321 		timerclear(&tv);
322 		tv.tv_sec = TAILQ_FIRST(&nbr->ls_retrans_list)->le_when;
323 
324 		if (evtimer_add(&nbr->ls_retrans_timer, &tv) == -1)
325 			fatal("ls_retrans_list_add");
326 	}
327 }
328 
329 int
330 ls_retrans_list_del(struct nbr *nbr, struct lsa_hdr *lsa_hdr)
331 {
332 	struct lsa_entry	*le;
333 
334 	if ((le = ls_retrans_list_get(nbr, lsa_hdr)) == NULL)
335 		return (-1);
336 	/*
337 	 * Compare LSA with the Ack by comparing not only the seq_num and
338 	 * checksum but also the age field.  Since we only care about MAX_AGE
339 	 * vs. non-MAX_AGE LSA, a simple >= comparison is good enough.  This
340 	 * ensures that a LSA withdrawal is not acked by a previous update.
341 	 */
342 	if (lsa_hdr->seq_num == le->le_ref->hdr.seq_num &&
343 	    lsa_hdr->ls_chksum == le->le_ref->hdr.ls_chksum &&
344 	    ntohs(lsa_hdr->age) >= ntohs(le->le_ref->hdr.age)) {
345 		ls_retrans_list_free(nbr, le);
346 		return (0);
347 	}
348 
349 	return (-1);
350 }
351 
352 struct lsa_entry *
353 ls_retrans_list_get(struct nbr *nbr, struct lsa_hdr *lsa_hdr)
354 {
355 	struct lsa_entry	*le;
356 
357 	TAILQ_FOREACH(le, &nbr->ls_retrans_list, entry) {
358 		if ((lsa_hdr->type == le->le_ref->hdr.type) &&
359 		    (lsa_hdr->ls_id == le->le_ref->hdr.ls_id) &&
360 		    (lsa_hdr->adv_rtr == le->le_ref->hdr.adv_rtr))
361 			return (le);
362 	}
363 	return (NULL);
364 }
365 
366 void
367 ls_retrans_list_insert(struct nbr *nbr, struct lsa_entry *new)
368 {
369 	struct lsa_entry	*le;
370 	unsigned short		 when = new->le_when;
371 
372 	TAILQ_FOREACH(le, &nbr->ls_retrans_list, entry) {
373 		if (when < le->le_when) {
374 			new->le_when = when;
375 			TAILQ_INSERT_BEFORE(le, new, entry);
376 			nbr->ls_ret_cnt++;
377 			return;
378 		}
379 		when -= le->le_when;
380 	}
381 	new->le_when = when;
382 	TAILQ_INSERT_TAIL(&nbr->ls_retrans_list, new, entry);
383 	nbr->ls_ret_cnt++;
384 }
385 
386 void
387 ls_retrans_list_remove(struct nbr *nbr, struct lsa_entry *le)
388 {
389 	struct timeval		 tv;
390 	struct lsa_entry	*next = TAILQ_NEXT(le, entry);
391 	int			 reset = 0;
392 
393 	/* adjust timeout of next entry */
394 	if (next)
395 		next->le_when += le->le_when;
396 
397 	if (TAILQ_FIRST(&nbr->ls_retrans_list) == le &&
398 	    evtimer_pending(&nbr->ls_retrans_timer, NULL))
399 		reset = 1;
400 
401 	TAILQ_REMOVE(&nbr->ls_retrans_list, le, entry);
402 	nbr->ls_ret_cnt--;
403 
404 	if (reset && TAILQ_FIRST(&nbr->ls_retrans_list)) {
405 		if (evtimer_del(&nbr->ls_retrans_timer) == -1)
406 			fatal("ls_retrans_list_remove");
407 
408 		timerclear(&tv);
409 		tv.tv_sec = TAILQ_FIRST(&nbr->ls_retrans_list)->le_when;
410 
411 		if (evtimer_add(&nbr->ls_retrans_timer, &tv) == -1)
412 			fatal("ls_retrans_list_remove");
413 	}
414 }
415 
416 void
417 ls_retrans_list_free(struct nbr *nbr, struct lsa_entry *le)
418 {
419 	ls_retrans_list_remove(nbr, le);
420 
421 	lsa_cache_put(le->le_ref, nbr);
422 	free(le);
423 }
424 
425 void
426 ls_retrans_list_clr(struct nbr *nbr)
427 {
428 	struct lsa_entry	*le;
429 
430 	while ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL)
431 		ls_retrans_list_free(nbr, le);
432 
433 	nbr->ls_ret_cnt = 0;
434 }
435 
436 /* ARGSUSED */
437 void
438 ls_retrans_timer(int fd, short event, void *bula)
439 {
440 	struct timeval		 tv;
441 	struct timespec		 tp;
442 	struct in6_addr		 addr;
443 	struct nbr		*nbr = bula;
444 	struct lsa_entry	*le;
445 	struct ibuf		*buf;
446 	time_t			 now;
447 	int			 d, bigpkt;
448 	u_int32_t		 nlsa = 0;
449 
450 	if ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL)
451 		le->le_when = 0;	/* timer fired */
452 	else
453 		return;			/* queue empty, nothing to do */
454 
455 	clock_gettime(CLOCK_MONOTONIC, &tp);
456 	now = tp.tv_sec;
457 
458 	if (nbr->iface->self == nbr) {
459 		/*
460 		 * oneshot needs to be set for lsa queued for flooding,
461 		 * if oneshot is not set then the lsa needs to be converted
462 		 * because the router switched lately to DR or BDR
463 		 */
464 		if (le->le_oneshot && nbr->iface->state & IF_STA_DRORBDR)
465 			inet_pton(AF_INET6, AllSPFRouters, &addr);
466 		else if (nbr->iface->state & IF_STA_DRORBDR) {
467 			/*
468 			 * old retransmission needs to be converted into
469 			 * flood by rerunning the lsa_flood.
470 			 */
471 			lsa_flood(nbr->iface, nbr, &le->le_ref->hdr,
472 			    le->le_ref->data);
473 			ls_retrans_list_free(nbr, le);
474 			/* ls_retrans_list_free retriggers the timer */
475 			return;
476 		} else if (nbr->iface->type == IF_TYPE_POINTOPOINT)
477 			memcpy(&addr, &nbr->iface->dst, sizeof(addr));
478 		else
479 			inet_pton(AF_INET6, AllDRouters, &addr);
480 	} else
481 		memcpy(&addr, &nbr->addr, sizeof(addr));
482 
483 	bigpkt = le->le_ref->len > 1024;
484 	if ((buf = prepare_ls_update(nbr->iface, bigpkt)) == NULL) {
485 		le->le_when = 1;
486 		goto done;
487 	}
488 
489 	while ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL &&
490 	    le->le_when == 0) {
491 		d = now - le->le_ref->stamp;
492 		if (d < 0)
493 			d = 0;
494 		else if (d > MAX_AGE)
495 			d = MAX_AGE;
496 
497 		if (add_ls_update(buf, nbr->iface, le->le_ref->data,
498 		    le->le_ref->len, d) == 0) {
499 			if (nlsa == 0) {
500 				/* something bad happened retry later */
501 				log_warnx("ls_retrans_timer: sending LS update "
502 				    "to neighbor ID %s failed",
503 				    inet_ntoa(nbr->id));
504 				log_debug("ls_retrans_timer: type: %04x len: %u",
505 				    ntohs(le->le_ref->hdr.type),
506 				    le->le_ref->len);
507 				TAILQ_REMOVE(&nbr->ls_retrans_list, le, entry);
508 				nbr->ls_ret_cnt--;
509 				le->le_when = nbr->iface->rxmt_interval;
510 				ls_retrans_list_insert(nbr, le);
511 			}
512 			break;
513 		}
514 		nlsa++;
515 		if (le->le_oneshot)
516 			ls_retrans_list_free(nbr, le);
517 		else {
518 			TAILQ_REMOVE(&nbr->ls_retrans_list, le, entry);
519 			nbr->ls_ret_cnt--;
520 			le->le_when = nbr->iface->rxmt_interval;
521 			ls_retrans_list_insert(nbr, le);
522 		}
523 	}
524 	if (nlsa)
525 		send_ls_update(buf, nbr->iface, addr, nlsa);
526 	else
527 		ibuf_free(buf);
528 
529 done:
530 	if ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL) {
531 		timerclear(&tv);
532 		tv.tv_sec = le->le_when;
533 
534 		if (evtimer_add(&nbr->ls_retrans_timer, &tv) == -1)
535 			fatal("ls_retrans_timer");
536 	}
537 }
538 
539 LIST_HEAD(lsa_cache_head, lsa_ref);
540 
541 struct lsa_cache {
542 	struct lsa_cache_head	*hashtbl;
543 	u_int32_t		 hashmask;
544 } lsacache;
545 
546 SIPHASH_KEY lsacachekey;
547 
548 struct lsa_ref		*lsa_cache_look(struct lsa_hdr *);
549 
550 void
551 lsa_cache_init(u_int32_t hashsize)
552 {
553 	u_int32_t        hs, i;
554 
555 	for (hs = 1; hs < hashsize; hs <<= 1)
556 		;
557 	lsacache.hashtbl = calloc(hs, sizeof(struct lsa_cache_head));
558 	if (lsacache.hashtbl == NULL)
559 		fatal("lsa_cache_init");
560 
561 	for (i = 0; i < hs; i++)
562 		LIST_INIT(&lsacache.hashtbl[i]);
563 	arc4random_buf(&lsacachekey, sizeof(lsacachekey));
564 
565 	lsacache.hashmask = hs - 1;
566 }
567 
568 static uint32_t
569 lsa_hash_hdr(const struct lsa_hdr *hdr)
570 {
571 	return SipHash24(&lsacachekey, hdr, sizeof(*hdr));
572 }
573 
574 struct lsa_ref *
575 lsa_cache_add(void *data, u_int16_t len)
576 {
577 	struct lsa_cache_head	*head;
578 	struct lsa_ref		*ref, *old;
579 	struct timespec		 tp;
580 
581 	if ((ref = calloc(1, sizeof(*ref))) == NULL)
582 		fatal("lsa_cache_add");
583 	memcpy(&ref->hdr, data, sizeof(ref->hdr));
584 
585 	if ((old = lsa_cache_look(&ref->hdr))) {
586 		free(ref);
587 		old->refcnt++;
588 		return (old);
589 	}
590 
591 	if ((ref->data = malloc(len)) == NULL)
592 		fatal("lsa_cache_add");
593 	memcpy(ref->data, data, len);
594 
595 	clock_gettime(CLOCK_MONOTONIC, &tp);
596 	ref->stamp = tp.tv_sec;
597 	ref->len = len;
598 	ref->refcnt = 1;
599 
600 	head = &lsacache.hashtbl[lsa_hash_hdr(&ref->hdr) & lsacache.hashmask];
601 	LIST_INSERT_HEAD(head, ref, entry);
602 	return (ref);
603 }
604 
605 struct lsa_ref *
606 lsa_cache_get(struct lsa_hdr *lsa_hdr)
607 {
608 	struct lsa_ref		*ref;
609 
610 	ref = lsa_cache_look(lsa_hdr);
611 	if (ref)
612 		ref->refcnt++;
613 
614 	return (ref);
615 }
616 
617 void
618 lsa_cache_put(struct lsa_ref *ref, struct nbr *nbr)
619 {
620 	if (--ref->refcnt > 0)
621 		return;
622 
623 	if (ntohs(ref->hdr.age) >= MAX_AGE)
624 		ospfe_imsg_compose_rde(IMSG_LS_MAXAGE, nbr->peerid, 0,
625 		    ref->data, sizeof(struct lsa_hdr));
626 
627 	free(ref->data);
628 	LIST_REMOVE(ref, entry);
629 	free(ref);
630 }
631 
632 struct lsa_ref *
633 lsa_cache_look(struct lsa_hdr *lsa_hdr)
634 {
635 	struct lsa_cache_head	*head;
636 	struct lsa_ref		*ref;
637 
638 	head = &lsacache.hashtbl[lsa_hash_hdr(lsa_hdr) & lsacache.hashmask];
639 
640 	LIST_FOREACH(ref, head, entry) {
641 		if (memcmp(&ref->hdr, lsa_hdr, sizeof(*lsa_hdr)) == 0)
642 			/* found match */
643 			return (ref);
644 	}
645 
646 	return (NULL);
647 }
648