source: mainline/uspace/lib/nettl/src/amap.c@ 0b2d369

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0b2d369 was e1b4ae0, checked in by Jiri Svoboda <jiri@…>, 8 years ago

Start adding tests for TCP conn module. Make sure all connections have been freed at the end of a test.

  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libnettl
30 * @{
31 */
32
33/**
34 * @file Association map
35 *
36 * Manages allocations of endpoints / endpoint pairs (corresponding to
37 * UDP associations, TCP listeners and TCP connections)
38 *
39 * An association map contains different types of entries, based on which
40 * set of attributes (key) they specify. In order from most specific to the
41 * least specific one:
42 *
43 * - repla (remote endpoint, local address)
44 * - laddr (local address)
45 * - llink (local link)
46 * - unspec (unspecified)
47 *
48 * In the unspecified case only the local port is known and the entry matches
49 * all remote and local addresses.
50 */
51
52#include <adt/list.h>
53#include <errno.h>
54#include <inet/addr.h>
55#include <inet/inet.h>
56#include <io/log.h>
57#include <nettl/amap.h>
58#include <stdint.h>
59#include <stdlib.h>
60
61/** Create association map.
62 *
63 * @param rmap Place to store pointer to new association map
64 * @return EOk on success, ENOMEM if out of memory
65 */
66int amap_create(amap_t **rmap)
67{
68 amap_t *map;
69 int rc;
70
71 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_create()");
72
73 map = calloc(1, sizeof(amap_t));
74 if (map == NULL)
75 return ENOMEM;
76
77 rc = portrng_create(&map->unspec);
78 if (rc != EOK) {
79 assert(rc == ENOMEM);
80 free(map);
81 return ENOMEM;
82 }
83
84 list_initialize(&map->repla);
85 list_initialize(&map->laddr);
86 list_initialize(&map->llink);
87
88 *rmap = map;
89 return EOK;
90}
91
92/** Destroy association map.
93 *
94 * @param map Association map
95 */
96void amap_destroy(amap_t *map)
97{
98 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_destroy()");
99
100 assert(list_empty(&map->repla));
101 assert(list_empty(&map->laddr));
102 assert(list_empty(&map->llink));
103 free(map);
104}
105
106/** Find exact repla.
107 *
108 * Find repla (remote endpoint, local address) entry by exact match.
109 *
110 * @param map Association map
111 * @param rep Remote endpoint
112 * @param la Local address
113 * @param rrepla Place to store pointer to repla
114 *
115 * @return EOK on success, ENOENT if not found
116 */
117static int amap_repla_find(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
118 amap_repla_t **rrepla)
119{
120 char *sraddr, *sladdr;
121
122 (void) inet_addr_format(&rep->addr, &sraddr);
123 (void) inet_addr_format(la, &sladdr);
124
125 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_repla_find(): rep=(%s,%" PRIu16
126 ") la=%s", sraddr, rep->port, sladdr);
127 free(sraddr);
128 free(sladdr);
129
130 list_foreach(map->repla, lamap, amap_repla_t, repla) {
131 (void) inet_addr_format(&repla->rep.addr, &sraddr);
132 (void) inet_addr_format(&repla->laddr, &sladdr);
133 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_repla_find(): "
134 "compare to rep=(%s, %" PRIu16 ") la=%s",
135 sraddr, repla->rep.port, sladdr);
136 free(sraddr);
137 free(sladdr);
138 if (inet_addr_compare(&repla->rep.addr, &rep->addr) &&
139 repla->rep.port == rep->port &&
140 inet_addr_compare(&repla->laddr, la)) {
141 *rrepla = repla;
142 return EOK;
143 }
144 }
145
146 *rrepla = NULL;
147 return ENOENT;
148}
149
150/** Insert repla.
151 *
152 * Insert new repla (remote endpoint, local address) entry to association map.
153 *
154 * @param amap Association map
155 * @param rep Remote endpoint
156 * @param la Local address
157 * @param rrepla Place to store pointer to new repla
158 *
159 * @return EOK on success, ENOMEM if out of memory
160 */
161static int amap_repla_insert(amap_t *map, inet_ep_t *rep, inet_addr_t *la,
162 amap_repla_t **rrepla)
163{
164 amap_repla_t *repla;
165 int rc;
166
167 repla = calloc(1, sizeof(amap_repla_t));
168 if (repla == NULL) {
169 *rrepla = NULL;
170 return ENOMEM;
171 }
172
173 rc = portrng_create(&repla->portrng);
174 if (rc != EOK) {
175 free(repla);
176 return ENOMEM;
177 }
178
179 repla->rep = *rep;
180 repla->laddr = *la;
181 list_append(&repla->lamap, &map->repla);
182
183 *rrepla = repla;
184 return EOK;
185}
186
187/** Remove repla from association map.
188 *
189 * Remove repla (remote endpoint, local address) from association map.
190 *
191 * @param map Association map
192 * @param repla Repla
193 */
194static void amap_repla_remove(amap_t *map, amap_repla_t *repla)
195{
196 list_remove(&repla->lamap);
197 portrng_destroy(repla->portrng);
198 free(repla);
199}
200
201/** Find exact laddr.
202 *
203 * Find laddr (local address) entry by exact match.
204 *
205 * @param map Association map
206 * @param addr Address
207 * @param rladdr Place to store pointer to laddr entry
208 *
209 * @return EOK on success, ENOENT if not found.
210 */
211static int amap_laddr_find(amap_t *map, inet_addr_t *addr,
212 amap_laddr_t **rladdr)
213{
214 list_foreach(map->laddr, lamap, amap_laddr_t, laddr) {
215 if (inet_addr_compare(&laddr->laddr, addr)) {
216 *rladdr = laddr;
217 return EOK;
218 }
219 }
220
221 *rladdr = NULL;
222 return ENOENT;
223}
224
225/** Insert laddr.
226 *
227 * Insert new laddr (local address) entry to association map.
228 *
229 * @param addr Local address
230 * @param rladdr Place to store pointer to new laddr
231 *
232 * @return EOK on success, ENOMEM if out of memory
233 */
234static int amap_laddr_insert(amap_t *map, inet_addr_t *addr,
235 amap_laddr_t **rladdr)
236{
237 amap_laddr_t *laddr;
238 int rc;
239
240 laddr = calloc(1, sizeof(amap_laddr_t));
241 if (laddr == NULL) {
242 *rladdr = NULL;
243 return ENOMEM;
244 }
245
246 rc = portrng_create(&laddr->portrng);
247 if (rc != EOK) {
248 free(laddr);
249 return ENOMEM;
250 }
251
252 laddr->laddr = *addr;
253 list_append(&laddr->lamap, &map->laddr);
254
255 *rladdr = laddr;
256 return EOK;
257}
258
259/** Remove laddr from association map.
260 *
261 * Remove laddr (local address) entry from association map.
262 *
263 * @param map Association map
264 * @param laddr Laddr entry
265 */
266static void amap_laddr_remove(amap_t *map, amap_laddr_t *laddr)
267{
268 list_remove(&laddr->lamap);
269 portrng_destroy(laddr->portrng);
270 free(laddr);
271}
272
273/** Find exact llink.
274 *
275 * Find llink (local link) entry by exact match.
276 *
277 * @param map Association map
278 * @param link_id Local link ID
279 * @param rllink Place to store pointer to llink entry
280 *
281 * @return EOK on success, ENOENT if not found.
282 */
283static int amap_llink_find(amap_t *map, sysarg_t link_id,
284 amap_llink_t **rllink)
285{
286 list_foreach(map->llink, lamap, amap_llink_t, llink) {
287 if (llink->llink == link_id) {
288 *rllink = llink;
289 return EOK;
290 }
291 }
292
293 *rllink = NULL;
294 return ENOENT;
295}
296
297/** Insert llink.
298 *
299 * Insert new llink (local link) entry to association map.
300 *
301 * @param link_id Local link
302 * @param rllink Place to store pointer to new llink
303 *
304 * @return EOK on success, ENOMEM if out of memory
305 */
306static int amap_llink_insert(amap_t *map, sysarg_t link_id,
307 amap_llink_t **rllink)
308{
309 amap_llink_t *llink;
310 int rc;
311
312 llink = calloc(1, sizeof(amap_llink_t));
313 if (llink == NULL) {
314 *rllink = NULL;
315 return ENOMEM;
316 }
317
318 rc = portrng_create(&llink->portrng);
319 if (rc != EOK) {
320 free(llink);
321 return ENOMEM;
322 }
323
324 llink->llink = link_id;
325 list_append(&llink->lamap, &map->llink);
326
327 *rllink = llink;
328 return EOK;
329}
330
331/** Remove llink from association map.
332 *
333 * Remove llink (local link) entry from association map.
334 *
335 * @param map Association map
336 * @param llink Llink entry
337 */
338static void amap_llink_remove(amap_t *map, amap_llink_t *llink)
339{
340 list_remove(&llink->lamap);
341 portrng_destroy(llink->portrng);
342 free(llink);
343}
344
345/** Insert endpoint pair into map with repla as key.
346 *
347 * If local port number is not specified, it is allocated.
348 *
349 * @param map Association map
350 * @param epp Endpoint pair, possibly with local port inet_port_any
351 * @param arg arg User value
352 * @param flags Flags
353 * @param aepp Place to store actual endpoint pair, possibly with allocated port
354 *
355 * @return EOK on success, EEXIST if conflicting epp exists,
356 * ENOMEM if out of memory
357 */
358static int amap_insert_repla(amap_t *map, inet_ep2_t *epp, void *arg,
359 amap_flags_t flags, inet_ep2_t *aepp)
360{
361 amap_repla_t *repla;
362 inet_ep2_t mepp;
363 int rc;
364
365 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_repla()");
366
367 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
368 if (rc != EOK) {
369 /* New repla */
370 rc = amap_repla_insert(map, &epp->remote, &epp->local.addr,
371 &repla);
372 if (rc != EOK) {
373 assert(rc == ENOMEM);
374 return rc;
375 }
376 }
377
378 mepp = *epp;
379
380 rc = portrng_alloc(repla->portrng, epp->local.port, arg, flags,
381 &mepp.local.port);
382 if (rc != EOK) {
383 return rc;
384 }
385
386 *aepp = mepp;
387 return EOK;
388}
389
390/** Insert endpoint pair into map with laddr as key.
391 *
392 * If local port number is not specified, it is allocated.
393 *
394 * @param map Association map
395 * @param epp Endpoint pair, possibly with local port inet_port_any
396 * @param arg arg User value
397 * @param flags Flags
398 * @param aepp Place to store actual endpoint pair, possibly with allocated port
399 *
400 * @return EOK on success, EEXIST if conflicting epp exists,
401 * ENOMEM if out of memory
402 */
403static int amap_insert_laddr(amap_t *map, inet_ep2_t *epp, void *arg,
404 amap_flags_t flags, inet_ep2_t *aepp)
405{
406 amap_laddr_t *laddr;
407 inet_ep2_t mepp;
408 int rc;
409
410 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_laddr()");
411
412 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
413 if (rc != EOK) {
414 /* New laddr */
415 rc = amap_laddr_insert(map, &epp->local.addr, &laddr);
416 if (rc != EOK) {
417 assert(rc == ENOMEM);
418 return rc;
419 }
420 }
421
422 mepp = *epp;
423
424 rc = portrng_alloc(laddr->portrng, epp->local.port, arg, flags,
425 &mepp.local.port);
426 if (rc != EOK) {
427 return rc;
428 }
429
430 *aepp = mepp;
431 return EOK;
432}
433
434/** Insert endpoint pair into map with llink as key.
435 *
436 * If local port number is not specified, it is allocated.
437 *
438 * @param map Association map
439 * @param epp Endpoint pair, possibly with local port inet_port_any
440 * @param arg arg User value
441 * @param flags Flags
442 * @param aepp Place to store actual endpoint pair, possibly with allocated port
443 *
444 * @return EOK on success, EEXIST if conflicting epp exists,
445 * ENOMEM if out of memory
446 */
447static int amap_insert_llink(amap_t *map, inet_ep2_t *epp, void *arg,
448 amap_flags_t flags, inet_ep2_t *aepp)
449{
450 amap_llink_t *llink;
451 inet_ep2_t mepp;
452 int rc;
453
454 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_llink()");
455
456 rc = amap_llink_find(map, epp->local_link, &llink);
457 if (rc != EOK) {
458 /* New llink */
459 rc = amap_llink_insert(map, epp->local_link, &llink);
460 if (rc != EOK) {
461 assert(rc == ENOMEM);
462 return rc;
463 }
464 }
465
466 mepp = *epp;
467
468 rc = portrng_alloc(llink->portrng, epp->local.port, arg, flags,
469 &mepp.local.port);
470 if (rc != EOK) {
471 return rc;
472 }
473
474 *aepp = mepp;
475 return EOK;
476}
477
478/** Insert endpoint pair into map with unspec as key.
479 *
480 * If local port number is not specified, it is allocated.
481 *
482 * @param map Association map
483 * @param epp Endpoint pair, possibly with local port inet_port_any
484 * @param arg arg User value
485 * @param flags Flags
486 * @param aepp Place to store actual endpoint pair, possibly with allocated port
487 *
488 * @return EOK on success, EEXIST if conflicting epp exists,
489 * ENOMEM if out of memory
490 */
491static int amap_insert_unspec(amap_t *map, inet_ep2_t *epp, void *arg,
492 amap_flags_t flags, inet_ep2_t *aepp)
493{
494 inet_ep2_t mepp;
495 int rc;
496
497 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert_unspec()");
498 mepp = *epp;
499
500 rc = portrng_alloc(map->unspec, epp->local.port, arg, flags,
501 &mepp.local.port);
502 if (rc != EOK) {
503 return rc;
504 }
505
506 *aepp = mepp;
507 return EOK;
508}
509
510/** Insert endpoint pair into map.
511 *
512 * If local endpoint is not fully specified, it is filled in (determine
513 * source address, allocate port number). Checks for conflicting endpoint pair.
514 *
515 * @param map Association map
516 * @param epp Endpoint pair, possibly with local port inet_port_any
517 * @param arg arg User value
518 * @param flags Flags
519 * @param aepp Place to store actual endpoint pair, possibly with allocated port
520 *
521 * @return EOK on success, EEXIST if conflicting epp exists,
522 * ENOMEM if out of memory
523 */
524int amap_insert(amap_t *map, inet_ep2_t *epp, void *arg, amap_flags_t flags,
525 inet_ep2_t *aepp)
526{
527 bool raddr, rport, laddr, llink;
528 inet_ep2_t mepp;
529 int rc;
530
531 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert()");
532
533 mepp = *epp;
534
535 /* Fill in local address? */
536 if (!inet_addr_is_any(&epp->remote.addr) &&
537 inet_addr_is_any(&epp->local.addr)) {
538 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
539 "determine local address");
540 rc = inet_get_srcaddr(&epp->remote.addr, 0, &mepp.local.addr);
541 if (rc != EOK) {
542 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
543 "cannot determine local address");
544 return rc;
545 }
546 } else {
547 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: "
548 "local address specified or remote address not specified");
549 }
550
551 raddr = !inet_addr_is_any(&mepp.remote.addr);
552 rport = mepp.remote.port != inet_port_any;
553 laddr = !inet_addr_is_any(&mepp.local.addr);
554 llink = mepp.local_link != 0;
555
556 if (raddr && rport && laddr && !llink) {
557 return amap_insert_repla(map, &mepp, arg, flags, aepp);
558 } else if (!raddr && !rport && laddr && !llink) {
559 return amap_insert_laddr(map, &mepp, arg, flags, aepp);
560 } else if (!raddr && !rport && !laddr && llink) {
561 return amap_insert_llink(map, &mepp, arg, flags, aepp);
562 } else if (!raddr && !rport && !laddr && !llink) {
563 return amap_insert_unspec(map, &mepp, arg, flags, aepp);
564 } else {
565 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_insert: invalid "
566 "combination of raddr=%d rport=%d laddr=%d llink=%d",
567 raddr, rport, laddr, llink);
568 return EINVAL;
569 }
570
571 return EOK;
572}
573
574/** Remove endpoint pair using repla as key from map.
575 *
576 * The endpoint pair must be present in the map, otherwise behavior
577 * is unspecified.
578 *
579 * @param map Association map
580 * @param epp Endpoint pair
581 */
582static void amap_remove_repla(amap_t *map, inet_ep2_t *epp)
583{
584 amap_repla_t *repla;
585 int rc;
586
587 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
588 if (rc != EOK) {
589 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_repla: not found");
590 return;
591 }
592
593 portrng_free_port(repla->portrng, epp->local.port);
594
595 if (portrng_empty(repla->portrng))
596 amap_repla_remove(map, repla);
597}
598
599/** Remove endpoint pair using laddr as key from map.
600 *
601 * The endpoint pair must be present in the map, otherwise behavior
602 * is unspecified.
603 *
604 * @param map Association map
605 * @param epp Endpoint pair
606 */
607static void amap_remove_laddr(amap_t *map, inet_ep2_t *epp)
608{
609 amap_laddr_t *laddr;
610 int rc;
611
612 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
613 if (rc != EOK) {
614 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_laddr: not found");
615 return;
616 }
617
618 portrng_free_port(laddr->portrng, epp->local.port);
619
620 if (portrng_empty(laddr->portrng))
621 amap_laddr_remove(map, laddr);
622}
623
624/** Remove endpoint pair using llink as key from map.
625 *
626 * The endpoint pair must be present in the map, otherwise behavior
627 * is unspecified.
628 *
629 * @param map Association map
630 * @param epp Endpoint pair
631 */
632static void amap_remove_llink(amap_t *map, inet_ep2_t *epp)
633{
634 amap_llink_t *llink;
635 int rc;
636
637 rc = amap_llink_find(map, epp->local_link, &llink);
638 if (rc != EOK) {
639 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove_llink: not found");
640 return;
641 }
642
643 portrng_free_port(llink->portrng, epp->local.port);
644
645 if (portrng_empty(llink->portrng))
646 amap_llink_remove(map, llink);
647}
648
649/** Remove endpoint pair using unspec as key from map.
650 *
651 * The endpoint pair must be present in the map, otherwise behavior
652 * is unspecified.
653 *
654 * @param map Association map
655 * @param epp Endpoint pair
656 */
657static void amap_remove_unspec(amap_t *map, inet_ep2_t *epp)
658{
659 portrng_free_port(map->unspec, epp->local.port);
660}
661
662/** Remove endpoint pair from map.
663 *
664 * The endpoint pair must be present in the map, otherwise behavior
665 * is unspecified.
666 *
667 * @param map Association map
668 * @param epp Endpoint pair
669 */
670void amap_remove(amap_t *map, inet_ep2_t *epp)
671{
672 bool raddr, rport, laddr, llink;
673
674 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove()");
675
676 raddr = !inet_addr_is_any(&epp->remote.addr);
677 rport = epp->remote.port != inet_port_any;
678 laddr = !inet_addr_is_any(&epp->local.addr);
679 llink = epp->local_link != 0;
680
681 if (raddr && rport && laddr && !llink) {
682 amap_remove_repla(map, epp);
683 } else if (!raddr && !rport && laddr && !llink) {
684 amap_remove_laddr(map, epp);
685 } else if (!raddr && !rport && !laddr && llink) {
686 amap_remove_llink(map, epp);
687 } else if (!raddr && !rport && !laddr && !llink) {
688 amap_remove_unspec(map, epp);
689 } else {
690 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_remove: invalid "
691 "combination of raddr=%d rport=%d laddr=%d llink=%d",
692 raddr, rport, laddr, llink);
693 return;
694 }
695}
696
697/** Find association matching an endpoint pair.
698 *
699 * Used to find which association to deliver a datagram to.
700 *
701 * @param map Association map
702 * @param epp Endpoint pair
703 * @param rarg Place to store user argument for the matching association.
704 *
705 * @return EOK on success, ENOENT if not found.
706 */
707int amap_find_match(amap_t *map, inet_ep2_t *epp, void **rarg)
708{
709 int rc;
710 amap_repla_t *repla;
711 amap_laddr_t *laddr;
712 amap_llink_t *llink;
713
714 log_msg(LOG_DEFAULT, LVL_DEBUG2, "amap_find_match(llink=%zu)",
715 epp->local_link);
716
717 /* Remode endpoint, local address */
718 rc = amap_repla_find(map, &epp->remote, &epp->local.addr, &repla);
719 if (rc == EOK) {
720 rc = portrng_find_port(repla->portrng, epp->local.port,
721 rarg);
722 if (rc == EOK) {
723 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched repla / "
724 "port %" PRIu16, epp->local.port);
725 return EOK;
726 }
727 }
728
729 /* Local address */
730 rc = amap_laddr_find(map, &epp->local.addr, &laddr);
731 if (rc == EOK) {
732 rc = portrng_find_port(laddr->portrng, epp->local.port,
733 rarg);
734 if (rc == EOK) {
735 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched laddr / "
736 "port %" PRIu16, epp->local.port);
737 return EOK;
738 }
739 }
740
741 /* Local link */
742 rc = amap_llink_find(map, epp->local_link, &llink);
743 if (epp->local_link != 0 && rc == EOK) {
744 rc = portrng_find_port(llink->portrng, epp->local.port,
745 rarg);
746 if (rc == EOK) {
747 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched llink / "
748 "port %" PRIu16, epp->local.port);
749 return EOK;
750 }
751 }
752
753 /* Unspecified */
754 rc = portrng_find_port(map->unspec, epp->local.port, rarg);
755 if (rc == EOK) {
756 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Matched unspec / port %" PRIu16,
757 epp->local.port);
758 return EOK;
759 }
760
761 log_msg(LOG_DEFAULT, LVL_DEBUG2, "No match.");
762 return ENOENT;
763}
764
765/**
766 * @}
767 */
Note: See TracBrowser for help on using the repository browser.