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); } } -- 1.9.1 _______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
