From: James Li <[email protected]>
Allow ospf to use unnumbered links by utilizing the loopback interface IP
address.
Example Config:
interface lo:1
address 10.2.1.3/32
int swp1
ip ospf network point-to-point
int swp2
ip ospf network point-to-point
router ospf
ospf router-id 10.2.1.3
network 10.2.1.3/32 area 0.0.0.0
Signed-off-by: James Li <[email protected]>
Signed-off-by: Dinesh Dutt <[email protected]>
Reviewed-by: JR Rivers <[email protected]>
Signed-off-by: Donald Sharp <[email protected]>
---
ospfd/ospf_interface.c | 13 +++++++++---
ospfd/ospf_lsa.c | 39 ++++++++++++++++++++++++-----------
ospfd/ospf_route.c | 2 +-
ospfd/ospf_vty.c | 55 ++++++++++++++++++++++++++++----------------------
ospfd/ospf_zebra.c | 25 +++++++++++++++++++++--
5 files changed, 92 insertions(+), 42 deletions(-)
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index f41c4f1..85494f4 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -351,7 +351,12 @@ ospf_if_is_configured (struct ospf *ospf, struct in_addr
*address)
for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
{
- if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+ {
+ if (htonl(oi->ifp->ifindex) == address->s_addr)
+ return oi;
+ }
+ else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
{
/* special leniency: match if addr is anywhere on peer subnet */
if (prefix_match(CONNECTED_PREFIX(oi->connected),
@@ -475,8 +480,10 @@ ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr
src,
if (if_is_loopback (oi->ifp))
continue;
- if (prefix_match (CONNECTED_PREFIX(oi->connected),
- (struct prefix *) &addr))
+ if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+ match = oi;
+ else if (prefix_match (CONNECTED_PREFIX(oi->connected),
+ (struct prefix *) &addr))
{
if ( (match == NULL) ||
(match->address->prefixlen < oi->address->prefixlen)
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 05587e8..8d18120 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -543,7 +543,7 @@ lsa_link_ptop_set (struct stream *s, struct ospf_interface
*oi)
{
int links = 0;
struct ospf_neighbor *nbr;
- struct in_addr id, mask;
+ struct in_addr id, mask, data;
u_int16_t cost = ospf_link_cost (oi);
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
@@ -552,19 +552,34 @@ lsa_link_ptop_set (struct stream *s, struct
ospf_interface *oi)
if ((nbr = ospf_nbr_lookup_ptop (oi)))
if (nbr->state == NSM_Full)
{
- /* For unnumbered point-to-point networks, the Link Data field
- should specify the interface's MIB-II ifIndex value. */
- links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
- LSA_LINK_TYPE_POINTOPOINT, 0, cost);
+ if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+ {
+ /* For unnumbered point-to-point networks, the Link Data field
+ should specify the interface's MIB-II ifIndex value. */
+ data.s_addr = htonl(oi->ifp->ifindex);
+ links += link_info_set (s, nbr->router_id, data,
+ LSA_LINK_TYPE_POINTOPOINT, 0, cost);
+ }
+ else
+ {
+ links += link_info_set (s, nbr->router_id,
+ oi->address->u.prefix4,
+ LSA_LINK_TYPE_POINTOPOINT, 0, cost);
+ }
}
- /* Regardless of the state of the neighboring router, we must
- add a Type 3 link (stub network).
- N.B. Options 1 & 2 share basically the same logic. */
- masklen2ip (oi->address->prefixlen, &mask);
- id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
- links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
- oi->output_cost);
+ /* no need for a stub link for unnumbered interfaces */
+ if (!CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
+ {
+ /* Regardless of the state of the neighboring router, we must
+ add a Type 3 link (stub network).
+ N.B. Options 1 & 2 share basically the same logic. */
+ masklen2ip (oi->address->prefixlen, &mask);
+ id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr &
mask.s_addr;
+ links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
+ oi->output_cost);
+ }
+
return links;
}
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index eb7829a..51e6eba 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -783,7 +783,7 @@ ospf_route_copy_nexthops_from_vertex (struct ospf_route *to,
path = ospf_path_new ();
path->nexthop = nexthop->router;
path->ifindex = nexthop->oi->ifp->ifindex;
- listnode_add (to->paths, path);
+ listnode_add (to->paths, path);
}
}
}
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index d9038c8..7f8ff0e 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3011,30 +3011,37 @@ show_ip_ospf_interface_sub (struct vty *vty, struct
ospf *ospf,
if (oi == NULL)
continue;
- /* Show OSPF interface information. */
- vty_out (vty, " Internet Address %s/%d,",
- inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen);
-
- if (oi->connected->destination || oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
{
- struct in_addr *dest;
- const char *dstr;
-
- if (CONNECTED_PEER(oi->connected)
- || oi->type == OSPF_IFTYPE_VIRTUALLINK)
- dstr = "Peer";
- else
- dstr = "Broadcast";
-
- /* For Vlinks, showing the peer address is probably more
- * informative than the local interface that is being used
- */
- if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
- dest = &oi->vl_data->peer_addr;
- else
- dest = &oi->connected->destination->u.prefix4;
-
- vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest));
+ vty_out (vty, " This interface is UNNUMBERED,");
+ }
+ else
+ {
+ /* Show OSPF interface information. */
+ vty_out (vty, " Internet Address %s/%d,",
+ inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen);
+
+ if (oi->connected->destination || oi->type ==
OSPF_IFTYPE_VIRTUALLINK)
+ {
+ struct in_addr *dest;
+ const char *dstr;
+
+ if (CONNECTED_PEER(oi->connected)
+ || oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ dstr = "Peer";
+ else
+ dstr = "Broadcast";
+
+ /* For Vlinks, showing the peer address is probably more
+ * informative than the local interface that is being used
+ */
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ dest = &oi->vl_data->peer_addr;
+ else
+ dest = &oi->connected->destination->u.prefix4;
+
+ vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest));
+ }
}
vty_out (vty, " Area %s%s", ospf_area_desc_string (oi->area),
@@ -3086,7 +3093,7 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf
*ospf,
inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE);
}
}
-
+
/* Next network-LSA sequence number we'll use, if we're elected DR */
if (oi->params && ntohl (oi->params->network_lsa_seqnum)
!= OSPF_INITIAL_SEQUENCE_NUMBER)
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 83a0ba2..790a4c1 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -379,6 +379,26 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route
*or)
/* Nexthop, ifindex, distance and metric information. */
for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
{
+ if ((path->nexthop.s_addr != INADDR_ANY &&
+ path->ifindex != 0))
+ {
+ stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
+ stream_put_in_addr (s, &path->nexthop);
+ stream_putl (s, path->ifindex);
+ }
+ else if (path->nexthop.s_addr != INADDR_ANY)
+ {
+ stream_putc (s, ZEBRA_NEXTHOP_IPV4);
+ stream_put_in_addr (s, &path->nexthop);
+ }
+ else
+ {
+ stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
+ if (path->ifindex)
+ stream_putl (s, path->ifindex);
+ else
+ stream_putl (s, 0);
+ }
if (path->nexthop.s_addr != INADDR_ANY &&
path->ifindex != 0)
{
@@ -403,12 +423,13 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route
*or)
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
{
char buf[2][INET_ADDRSTRLEN];
- zlog_debug("Zebra: Route add %s/%d nexthop %s",
+ zlog_debug("Zebra: Route add %s/%d nexthop %s, ifindex=%d",
inet_ntop(AF_INET, &p->prefix,
buf[0], sizeof(buf[0])),
p->prefixlen,
inet_ntop(AF_INET, &path->nexthop,
- buf[1], sizeof(buf[1])));
+ buf[1], sizeof(buf[1])),
+ path->ifindex);
}
}