diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-09-07 15:06:47 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-12-22 02:26:08 +0100 |
commit | d8424057d97804284d0671076116ccc23d4d619c (patch) | |
tree | 1a08ea083cb9d3d92fc3f28258fcd35dd3c55cba /pimd | |
parent | pimd: Allow breaking up of packet. (diff) | |
download | frr-d8424057d97804284d0671076116ccc23d4d619c.tar.xz frr-d8424057d97804284d0671076116ccc23d4d619c.zip |
pimd: Allow ip address selection for BGP unnumbered
When a interface is configured as BGP unnumbered, it
has a v6 LL address as well as no v4 addresses. In
this case let's look at the lo's ip address as the
primary address to use.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
rebase
Diffstat (limited to 'pimd')
-rw-r--r-- | pimd/pim_iface.c | 54 | ||||
-rw-r--r-- | pimd/pim_zebra.c | 37 |
2 files changed, 85 insertions, 6 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 43c5f4b14..e55ef30b3 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -498,6 +498,8 @@ void pim_if_addr_add_all(struct interface *ifp) struct connected *ifc; struct listnode *node; struct listnode *nextnode; + int v4_addrs = 0; + int v6_addrs = 0; /* PIM/IGMP enabled ? */ if (!ifp->info) @@ -507,10 +509,35 @@ void pim_if_addr_add_all(struct interface *ifp) struct prefix *p = ifc->address; if (p->family != AF_INET) - continue; + { + v6_addrs++; + continue; + } + v4_addrs++; pim_if_addr_add(ifc); } + + if (!v4_addrs && v6_addrs && !if_is_loopback (ifp)) + { + struct pim_interface *pim_ifp = ifp->info; + + if (pim_ifp && PIM_IF_TEST_PIM(pim_ifp->options)) { + + /* Interface has a valid primary address ? */ + if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) { + + /* Interface has a valid socket ? */ + if (pim_ifp->pim_sock_fd < 0) { + if (pim_sock_add(ifp)) { + zlog_warn("Failure creating PIM socket for interface %s", + ifp->name); + } + } + + } + } /* pim */ + } } void pim_if_addr_del_all(struct interface *ifp) @@ -579,12 +606,17 @@ pim_find_primary_addr (struct interface *ifp) struct connected *ifc; struct listnode *node; struct in_addr addr; + int v4_addrs = 0; + int v6_addrs = 0; for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { struct prefix *p = ifc->address; - + if (p->family != AF_INET) - continue; + { + v6_addrs++; + continue; + } if (PIM_INADDR_IS_ANY(p->u.prefix4)) { zlog_warn("%s: null IPv4 address connected to interface %s", @@ -592,12 +624,28 @@ pim_find_primary_addr (struct interface *ifp) continue; } + v4_addrs++; + if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) continue; return p->u.prefix4; } + /* + * If we have no v4_addrs and v6 is configured + * We probably are using unnumbered + * So let's grab the loopbacks v4 address + * and use that as the primary address + */ + if (!v4_addrs && v6_addrs && !if_is_loopback (ifp)) + { + struct interface *lo_ifp; + lo_ifp = if_lookup_by_name_vrf ("lo", VRF_DEFAULT); + if (lo_ifp) + return pim_find_primary_addr (lo_ifp); + } + addr.s_addr = PIM_NET_INADDR_ANY; return addr; diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 68df086a1..f2789369b 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -236,9 +236,7 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient, return 0; p = c->address; - if (p->family != AF_INET) - return 0; - + if (PIM_DEBUG_ZEBRA) { char buf[BUFSIZ]; prefix2str(p, buf, BUFSIZ); @@ -252,6 +250,27 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient, #endif } + if (p->family != AF_INET) + { + struct pim_interface *pim_ifp = c->ifp->info; + struct listnode *cnode; + struct connected *conn; + int v4addrs = 0; + + for (ALL_LIST_ELEMENTS_RO (c->ifp->connected, cnode, conn)) + { + if (conn->address->family == AF_INET) + v4addrs++; + } + if (!v4addrs && pim_ifp) + { + + pim_ifp->primary_address = pim_find_primary_addr (c->ifp); + pim_if_addr_add_all (c->ifp); + } + return 0; + } + pim_rp_check_rp (old, p->u.prefix4); if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) { @@ -278,6 +297,18 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient, pim_if_addr_add(c); + if (if_is_loopback (c->ifp)) + { + struct listnode *ifnode; + struct interface *ifp; + + for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) + { + if (!if_is_loopback (ifp) && if_is_operative (ifp)) + pim_if_addr_add_all (ifp); + } + } + return 0; } |