diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2009-08-13 15:39:42 +0000 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2010-02-04 02:03:42 +0100 |
commit | 98dda61bc222aeccb754915954175d3ac8f8768d (patch) | |
tree | 8bc69242a15465ebff6dc27f22db63c943148148 | |
parent | 2f9994561e1a6547f9e55d41da85f755c97553f4 (diff) | |
download | quagga-98dda61bc222aeccb754915954175d3ac8f8768d.tar.bz2 quagga-98dda61bc222aeccb754915954175d3ac8f8768d.tar.xz |
ospfd: Update SPF calculation for unnumbered links
Add support for real unnumbered PtP interfaces in
ospf_nexthop_calculation().
Add ospf_if_lookup_by_ifindex() to support Unnumbered
PtP links. This version does not support:
- Multiple numbered PtP interfaces with the same IP address
between the same two routers.
- Unnumbered PtP on just one end of the link.
* ospfd/ospf_interface.c: Add ospf_if_lookup_by_ifindex().
* ospfd/ospf_interface.h: ditto.
* ospfd/ospf_spf.c: ospf_nexthop_calculation (), call
ospf_if_lookup_by_ifindex() for Unnumbered
PtP links.
-rw-r--r-- | ospfd/ospf_interface.c | 14 | ||||
-rw-r--r-- | ospfd/ospf_interface.h | 3 | ||||
-rw-r--r-- | ospfd/ospf_spf.c | 108 |
3 files changed, 81 insertions, 44 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index afe3acf1..775b121f 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -479,6 +479,20 @@ ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src, return match; } + +struct ospf_interface * +ospf_if_lookup_by_ifindex(struct ospf_area *area, unsigned int ifindex) +{ + struct listnode *node; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) + { + if (oi->ifp->ifindex == ifindex) + return oi; + } + return NULL; +} void ospf_if_stream_set (struct ospf_interface *oi) diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index c962d74c..e7823eeb 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -257,7 +257,8 @@ extern struct ospf_interface *ospf_if_lookup_recv_if (struct ospf *, struct interface *); extern struct ospf_interface *ospf_if_is_configured (struct ospf *, struct in_addr *); - +extern struct ospf_interface *ospf_if_lookup_by_ifindex(struct ospf_area *, + unsigned int); extern struct ospf_if_params *ospf_lookup_if_params (struct interface *, struct in_addr); extern struct ospf_if_params *ospf_get_if_params (struct interface *, diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index ca200222..f9ec11ba 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -529,6 +529,10 @@ ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v, if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT) { + int nh_found = 0; + struct in_addr nexthop; + unsigned long ifindex; + /* If the destination is a router which connects to the calculating router via a Point-to-MultiPoint network, the destination's next hop IP address(es) @@ -548,53 +552,71 @@ ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v, is a constituent of the PtMP link, and its address is a nexthop address for V. */ - oi = ospf_if_is_configured (area->ospf, &l->link_data); - if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) - { - struct prefix_ipv4 la; - - la.family = AF_INET; - la.prefixlen = oi->address->prefixlen; - - /* V links to W on PtMP interface - - find the interface address on W */ - while ((l2 = ospf_get_next_link (w, v, l2))) - { - la.prefix = l2->link_data; - - if (prefix_cmp ((struct prefix *) &la, - oi->address) == 0) - /* link_data is on our PtMP network */ - break; - } - } /* end l is on point-to-multipoint link */ - else - { - /* l is a regular point-to-point link. - Look for a link from W to V. - */ - while ((l2 = ospf_get_next_link (w, v, l2))) - { - oi = ospf_if_is_configured (area->ospf, - &(l2->link_data)); - - if (oi == NULL) - continue; - - if (!IPV4_ADDR_SAME (&oi->address->u.prefix4, - &l->link_data)) - continue; - - break; - } - } - - if (oi && l2) + ifindex = ntohl(l->link_data.s_addr); + if (ifindex <= 0x00ffffff) /* unnumbered ? */ + { + oi = ospf_if_lookup_by_ifindex(area, ifindex); + if (oi && oi->type == OSPF_IFTYPE_POINTOPOINT) + nh_found = 1; + nexthop.s_addr = 0; + } + else + { + oi = ospf_if_is_configured (area->ospf, &l->link_data); + if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + { + struct prefix_ipv4 la; + + la.family = AF_INET; + la.prefixlen = oi->address->prefixlen; + + /* V links to W on PtMP interface + - find the interface address on W */ + while ((l2 = ospf_get_next_link (w, v, l2))) + { + la.prefix = l2->link_data; + + if (prefix_cmp ((struct prefix *) &la, + oi->address) != 0) + continue; + /* link_data is on our PtMP network */ + nh_found = 1; + nexthop = l2->link_data; + break; + } + } /* end l is on point-to-multipoint link */ + else + { + /* l is a regular point-to-point link. + Look for a link from W to V. + */ + while ((l2 = ospf_get_next_link (w, v, l2))) + { + if (ntohl(l2->link_data.s_addr) <= 0x00ffffff) + continue; /* skip unnumbered links */ + + oi = ospf_if_is_configured (area->ospf, + &l2->link_data); + + if (oi == NULL) + continue; + + if (!IPV4_ADDR_SAME (&oi->address->u.prefix4, + &l->link_data)) + continue; + nexthop.s_addr = 0; /* zero better for equal-cost ? */ + nh_found = 1; + break; + } + } + } + + if (nh_found) { /* found all necessary info to build nexthop */ nh = vertex_nexthop_new (); nh->oi = oi; - nh->router = l2->link_data; + nh->router = nexthop; ospf_spf_add_parent (v, w, nh, distance); return 1; } |