struct ripng_peer *ripng_peer_lookup(struct ripng *ripng, struct in6_addr *addr) { struct ripng_peer *peer; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) { if (IPV6_ADDR_SAME(&peer->addr, addr)) return peer; } return NULL; }
static int bgp_nexthop_same (struct nexthop *next1, struct nexthop *next2) { if (next1->type != next2->type) return 0; switch (next1->type) { case ZEBRA_NEXTHOP_IPV4: if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4)) return 0; break; case ZEBRA_NEXTHOP_IPV4_IFINDEX: if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4) || next1->ifindex != next2->ifindex) return 0; break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: if (next1->ifindex != next2->ifindex) return 0; break; #ifdef HAVE_IPV6 case ZEBRA_NEXTHOP_IPV6: if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6)) return 0; break; case ZEBRA_NEXTHOP_IPV6_IFINDEX: case ZEBRA_NEXTHOP_IPV6_IFNAME: if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6)) return 0; if (next1->ifindex != next2->ifindex) return 0; break; #endif /* HAVE_IPV6 */ default: /* do nothing */ break; } return 1; }
/* * Return 1 if the address/netmask contained in the prefix structure * is the same, and else return 0. For this routine, 'same' requires * that not only the prefix length and the network part be the same, * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not * the same. Note that this routine has the same return value sense * as '==' (which is different from isis_prefix_cmp). */ int isis_prefix_same (const struct isis_prefix *p1, const struct isis_prefix *p2) { if (p1->family == p2->family && p1->prefixlen == p2->prefixlen) { if (p1->family == AF_INET) if (IPV4_ADDR_SAME (&p1->u.prefix, &p2->u.prefix)) return 1; #ifdef ENABLE_IPV6 if (p1->family == AF_INET6 ) if (IPV6_ADDR_SAME (&p1->u.prefix, &p2->u.prefix)) return 1; #endif /* ENABLE_IPV6 */ } return 0; }
/* * Return 1 if the address/netmask contained in the prefix structure * is the same, and else return 0. For this routine, 'same' requires * that not only the prefix length and the network part be the same, * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not * the same. Note that this routine has the same return value sense * as '==' (which is different from prefix_cmp). */ int prefix_same (const struct prefix *p1, const struct prefix *p2) { if (p1->family == p2->family && p1->prefixlen == p2->prefixlen) { if (p1->family == AF_INET) if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr)) return 1; #ifdef HAVE_IPV6 if (p1->family == AF_INET6 ) if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr)) return 1; #endif /* HAVE_IPV6 */ } return 0; }
/* If two connected address has same prefix return 1. */ static int connected_same_prefix (struct prefix *p1, struct prefix *p2) { if (p1->family == p2->family) { if (p1->family == AF_INET && IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4)) return 1; #ifdef HAVE_IPV6 if (p1->family == AF_INET6 && IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6)) return 1; #endif /* HAVE_IPV6 */ } return 0; }
/* * Return 1 if the address/netmask contained in the prefix structure * is the same, and else return 0. For this routine, 'same' requires * that not only the prefix length and the network part be the same, * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not * the same. Note that this routine has the same return value sense * as '==' (which is different from prefix_cmp). */ int prefix_same (const struct prefix *p1, const struct prefix *p2) { if (p1->family == p2->family && p1->prefixlen == p2->prefixlen) { if (p1->family == AF_INET) if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr)) return 1; #ifdef HAVE_IPV6 if (p1->family == AF_INET6 ) if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr)) return 1; #endif /* HAVE_IPV6 */ if (p1->family == AF_ETHERNET) { if (!memcmp(p1->u.prefix_eth.octet, p2->u.prefix_eth.octet, ETHER_ADDR_LEN)) return 1; } } return 0; }
struct interface * if_lookup_by_ipv6_exact (struct in6_addr *addr) { struct listnode *ifnode; struct listnode *cnode; struct interface *ifp; struct connected *connected; struct prefix *cp; for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp)) { for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) { cp = connected->address; if (cp->family == AF_INET6) if (IPV6_ADDR_SAME (&cp->u.prefix6, addr)) return ifp; } } return NULL; }
static int if_getaddrs(void) { int ret; struct ifaddrs *ifap; struct ifaddrs *ifapfree; struct interface *ifp; int prefixlen; ret = getifaddrs(&ifap); if (ret != 0) { zlog_err("getifaddrs(): %s", safe_strerror(errno)); return -1; } for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) { if (ifap->ifa_addr == NULL) { zlog_err ("%s: nonsensical ifaddr with NULL ifa_addr, ifname %s", __func__, (ifap->ifa_name ? ifap->ifa_name : "(null)")); continue; } ifp = if_lookup_by_name(ifap->ifa_name); if (ifp == NULL) { zlog_err("if_getaddrs(): Can't lookup interface %s\n", ifap->ifa_name); continue; } if (ifap->ifa_addr->sa_family == AF_INET) { struct sockaddr_in *addr; struct sockaddr_in *mask; struct sockaddr_in *dest; struct in_addr *dest_pnt; int flags = 0; addr = (struct sockaddr_in *)ifap->ifa_addr; mask = (struct sockaddr_in *)ifap->ifa_netmask; prefixlen = ip_masklen(mask->sin_addr); dest_pnt = NULL; if (ifap->ifa_dstaddr && !IPV4_ADDR_SAME(&addr->sin_addr, &((struct sockaddr_in *) ifap->ifa_dstaddr)->sin_addr)) { dest = (struct sockaddr_in *)ifap->ifa_dstaddr; dest_pnt = &dest->sin_addr; flags = ZEBRA_IFA_PEER; } else if (ifap->ifa_broadaddr && !IPV4_ADDR_SAME(&addr->sin_addr, &((struct sockaddr_in *) ifap-> ifa_broadaddr)->sin_addr)) { dest = (struct sockaddr_in *)ifap->ifa_broadaddr; dest_pnt = &dest->sin_addr; } connected_add_ipv4(ifp, flags, &addr->sin_addr, prefixlen, dest_pnt, NULL); } #ifdef HAVE_IPV6 if (ifap->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6 *addr; struct sockaddr_in6 *mask; struct sockaddr_in6 *dest; struct in6_addr *dest_pnt; int flags = 0; addr = (struct sockaddr_in6 *)ifap->ifa_addr; mask = (struct sockaddr_in6 *)ifap->ifa_netmask; prefixlen = ip6_masklen(mask->sin6_addr); dest_pnt = NULL; if (ifap->ifa_dstaddr && !IPV6_ADDR_SAME(&addr->sin6_addr, &((struct sockaddr_in6 *) ifap->ifa_dstaddr)->sin6_addr)) { dest = (struct sockaddr_in6 *)ifap->ifa_dstaddr; dest_pnt = &dest->sin6_addr; flags = ZEBRA_IFA_PEER; } else if (ifap->ifa_broadaddr && !IPV6_ADDR_SAME(&addr->sin6_addr, &((struct sockaddr_in6 *) ifap-> ifa_broadaddr)->sin6_addr)) { dest = (struct sockaddr_in6 *)ifap->ifa_broadaddr; dest_pnt = &dest->sin6_addr; } #if defined(KAME) if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { addr->sin6_scope_id = ntohs(*(u_int16_t *) & addr-> sin6_addr.s6_addr[2]); addr->sin6_addr.s6_addr[2] = addr->sin6_addr.s6_addr[3] = 0; } #endif connected_add_ipv6(ifp, flags, &addr->sin6_addr, prefixlen, dest_pnt, NULL); } #endif /* HAVE_IPV6 */ } freeifaddrs(ifapfree); return 0; }