summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2016-09-07 15:06:47 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-12-22 02:26:08 +0100
commitd8424057d97804284d0671076116ccc23d4d619c (patch)
tree1a08ea083cb9d3d92fc3f28258fcd35dd3c55cba /pimd
parentpimd: Allow breaking up of packet. (diff)
downloadfrr-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.c54
-rw-r--r--pimd/pim_zebra.c37
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;
}