struct ospf_interface * ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p) { struct listnode *node; struct ospf_interface *oi; struct prefix ptmp; /* Check each Interface. */ for (node = listhead (ospf->oiflist); node; nextnode (node)) { if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK) { if ((oi->type == OSPF_IFTYPE_POINTOPOINT) && CONNECTED_DEST_HOST(oi->connected)) { prefix_copy (&ptmp, oi->connected->destination); ptmp.prefixlen = IPV4_MAX_BITLEN; } else prefix_copy (&ptmp, oi->address); apply_mask (&ptmp); if (prefix_same (&ptmp, (struct prefix *) p)) return oi; } } return NULL; }
/* determine receiving interface by source of packet */ struct ospf_interface * ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src) { struct listnode *node; struct prefix_ipv4 addr; struct ospf_interface *oi, *match; addr.family = AF_INET; addr.prefix = src; addr.prefixlen = IPV4_MAX_BITLEN; match = NULL; for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { if (oi->type == OSPF_IFTYPE_VIRTUALLINK) continue; if (if_is_loopback (oi->ifp)) continue; if ((oi->type == OSPF_IFTYPE_POINTOPOINT) && CONNECTED_DEST_HOST(oi->connected)) { if (IPV4_ADDR_SAME (&oi->connected->destination->u.prefix4, &src)) return oi; } else { if (prefix_match (oi->address, (struct prefix *) &addr)) { if ( (match == NULL) || (match->address->prefixlen < oi->address->prefixlen) ) match = oi; } } } return match; }
/* * check if interface with given address is configured and * return it if yes. special treatment for PtP networks. */ struct ospf_interface * ospf_if_is_configured (struct ospf *ospf, struct in_addr *address) { struct listnode *node; struct ospf_interface *oi; struct prefix_ipv4 addr; addr.family = AF_INET; addr.prefix = *address; addr.prefixlen = IPV4_MAX_PREFIXLEN; for (node = listhead (ospf->oiflist); node; nextnode (node)) if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK) { if (oi->type == OSPF_IFTYPE_POINTOPOINT) { if (CONNECTED_DEST_HOST(oi->connected)) { /* match only destination addr, since local addr is most likely * not unique (borrowed from another interface) */ if (IPV4_ADDR_SAME (address, &oi->connected->destination->u.prefix4)) return oi; } else { /* special leniency: match if addr is anywhere on PtP subnet */ if (prefix_match(oi->address,(struct prefix *)&addr)) return oi; } } else { if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4)) return oi; } } return NULL; }