diff options
Diffstat (limited to 'pimd/pim_iface.c')
| -rw-r--r-- | pimd/pim_iface.c | 101 |
1 files changed, 60 insertions, 41 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index cce87ae5fd..f36a9b3cbb 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -1,21 +1,20 @@ /* - PIM for Quagga - Copyright (C) 2008 Everton da Silva Marques - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING; if not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ + * PIM for Quagga + * Copyright (C) 2008 Everton da Silva Marques + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include <zebra.h> @@ -61,7 +60,6 @@ pim_if_init (void) for (i = 0; i < MAXVIFS; i++) pim_iface_vif_index[i] = 0; - vrf_iflist_create(VRF_DEFAULT); pim_ifchannel_list = list_new(); pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare; } @@ -328,12 +326,29 @@ static int pim_sec_addr_comp(const void *p1, const void *p2) const struct pim_secondary_addr *sec1 = p1; const struct pim_secondary_addr *sec2 = p2; - if (ntohl(sec1->addr.s_addr) < ntohl(sec2->addr.s_addr)) + if (sec1->addr.family == AF_INET && + sec2->addr.family == AF_INET6) return -1; - if (ntohl(sec1->addr.s_addr) > ntohl(sec2->addr.s_addr)) + if (sec1->addr.family == AF_INET6 && + sec2->addr.family == AF_INET) return 1; + if (sec1->addr.family == AF_INET) + { + if (ntohl(sec1->addr.u.prefix4.s_addr) < ntohl(sec2->addr.u.prefix4.s_addr)) + return -1; + + if (ntohl(sec1->addr.u.prefix4.s_addr) > ntohl(sec2->addr.u.prefix4.s_addr)) + return 1; + } + else + { + return memcmp (&sec1->addr.u.prefix6, + &sec2->addr.u.prefix6, + sizeof (struct in6_addr)); + } + return 0; } @@ -343,7 +358,7 @@ static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr) } static struct pim_secondary_addr * -pim_sec_addr_find(struct pim_interface *pim_ifp, struct in_addr addr) +pim_sec_addr_find(struct pim_interface *pim_ifp, struct prefix *addr) { struct pim_secondary_addr *sec_addr; struct listnode *node; @@ -353,7 +368,7 @@ pim_sec_addr_find(struct pim_interface *pim_ifp, struct in_addr addr) } for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) { - if (sec_addr->addr.s_addr == addr.s_addr) { + if (prefix_cmp(&sec_addr->addr, addr)) { return sec_addr; } } @@ -368,7 +383,7 @@ static void pim_sec_addr_del(struct pim_interface *pim_ifp, pim_sec_addr_free(sec_addr); } -static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct in_addr addr) +static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr) { int changed = 0; struct pim_secondary_addr *sec_addr; @@ -395,7 +410,7 @@ static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct in_addr addr) } changed = 1; - sec_addr->addr = addr; + sec_addr->addr = *addr; listnode_add_sort(pim_ifp->sec_addr_list, sec_addr); return changed; @@ -437,10 +452,6 @@ static int pim_sec_addr_update(struct interface *ifp) for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { struct prefix *p = ifc->address; - if (p->family != AF_INET) { - continue; - } - if (PIM_INADDR_IS_ANY(p->u.prefix4)) { continue; } @@ -450,7 +461,7 @@ static int pim_sec_addr_update(struct interface *ifp) continue; } - if (pim_sec_addr_add(pim_ifp, p->u.prefix4)) { + if (pim_sec_addr_add(pim_ifp, p)) { changed = 1; } } @@ -575,12 +586,15 @@ void pim_if_addr_add(struct connected *ifc) detect_address_change(ifp, 0, __PRETTY_FUNCTION__); + if (ifc->address->family != AF_INET) + return; + if (PIM_IF_TEST_IGMP(pim_ifp->options)) { struct igmp_sock *igmp; /* lookup IGMP socket */ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, - ifaddr); + ifaddr); if (!igmp) { /* if addr new, add IGMP socket */ pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp); @@ -727,14 +741,17 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any) ifp = ifc->ifp; zassert(ifp); + if (ifc->address->family != AF_INET) + return; + if (PIM_DEBUG_ZEBRA) { char buf[BUFSIZ]; prefix2str(ifc->address, buf, BUFSIZ); zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s", - __PRETTY_FUNCTION__, - ifp->name, ifp->ifindex, buf, - CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? - "secondary" : "primary"); + __PRETTY_FUNCTION__, + ifp->name, ifp->ifindex, buf, + CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? + "secondary" : "primary"); } detect_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__); @@ -761,12 +778,9 @@ void pim_if_addr_add_all(struct interface *ifp) struct prefix *p = ifc->address; if (p->family != AF_INET) - { - v6_addrs++; - continue; - } - - v4_addrs++; + v6_addrs++; + else + v4_addrs++; pim_if_addr_add(ifc); } @@ -1157,6 +1171,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, struct listnode *neighnode; struct pim_neighbor *neigh; struct pim_interface *pim_ifp; + struct prefix p; zassert(ifp); @@ -1168,6 +1183,10 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, return 0; } + p.family = AF_INET; + p.u.prefix4 = addr; + p.prefixlen = IPV4_MAX_PREFIXLEN; + for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) { /* primary address ? */ @@ -1175,7 +1194,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, return neigh; /* secondary address ? */ - if (pim_neighbor_find_secondary(neigh, addr)) + if (pim_neighbor_find_secondary(neigh, &p)) return neigh; } |
