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 | 4 ++++ ospfd/ospf_route.h | 1 + ospfd/ospf_vty.c | 55 ++++++++++++++++++++++++++++---------------------- ospfd/ospf_zebra.c | 26 ++++++++++++++++++++++-- 6 files changed, 97 insertions(+), 41 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 e62a4e7..52b75d0 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..7efba7a 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -611,6 +611,8 @@ ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link, path = ospf_path_new (); path->nexthop.s_addr = 0; path->ifindex = oi->ifp->ifindex; + if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) + path->unnumbered = 1; listnode_add (or->paths, path); } else @@ -783,6 +785,8 @@ ospf_route_copy_nexthops_from_vertex (struct ospf_route *to, path = ospf_path_new (); path->nexthop = nexthop->router; path->ifindex = nexthop->oi->ifp->ifindex; + if (CHECK_FLAG(nexthop->oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) + path->unnumbered = 1; listnode_add (to->paths, path); } } diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index 6c202b0..4de3a3d 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -40,6 +40,7 @@ struct ospf_path struct in_addr nexthop; struct in_addr adv_router; unsigned int ifindex; + unsigned char unnumbered; }; /* Below is the structure linked to every diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 45a19c0..ac757b6 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2961,30 +2961,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), @@ -3036,7 +3043,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 cf2ea81..236d807 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -373,6 +373,27 @@ 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->unnumbered || + (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) { @@ -397,12 +418,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
