summaryrefslogtreecommitdiff
path: root/ospfd
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd')
-rw-r--r--ospfd/ospf_packet.c20
-rw-r--r--ospfd/ospf_route.c18
-rw-r--r--ospfd/ospf_route.h3
-rw-r--r--ospfd/ospf_snmp.c4
-rw-r--r--ospfd/ospf_spf.c20
-rw-r--r--ospfd/ospf_vty.c2
-rw-r--r--ospfd/ospf_zebra.c15
-rw-r--r--ospfd/ospfd.c221
-rw-r--r--ospfd/ospfd.h2
9 files changed, 168 insertions, 137 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index a778a50b..ed342e7f 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -3151,7 +3151,10 @@ ospf_db_desc_send (struct ospf_neighbor *nbr)
op->length = length;
/* Decide destination address. */
- op->dst = nbr->address.u.prefix4;
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
+ else
+ op->dst = nbr->address.u.prefix4;
/* Add packet to the interface output queue. */
ospf_packet_add (oi, op);
@@ -3210,7 +3213,10 @@ ospf_ls_req_send (struct ospf_neighbor *nbr)
op->length = length;
/* Decide destination address. */
- op->dst = nbr->address.u.prefix4;
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
+ else
+ op->dst = nbr->address.u.prefix4;
/* Add packet to the interface output queue. */
ospf_packet_add (oi, op);
@@ -3326,7 +3332,10 @@ ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
op->length = length;
/* Decide destination address. */
- op->dst.s_addr = addr.s_addr;
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
+ else
+ op->dst.s_addr = addr.s_addr;
/* Add packet to the interface output queue. */
ospf_packet_add (oi, op);
@@ -3403,13 +3412,12 @@ ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
/* Decide destination address. */
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
p.prefix = oi->vl_data->peer_addr;
+ else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
else if (flag == OSPF_SEND_PACKET_DIRECT)
p.prefix = nbr->address.u.prefix4;
else if (oi->state == ISM_DR || oi->state == ISM_Backup)
p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
- else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
- && (flag == OSPF_SEND_PACKET_INDIRECT))
- p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
else
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 3a1fa999..50fba750 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -481,7 +481,8 @@ ospf_intra_add_transit (struct route_table *rt, struct vertex *v,
/* RFC2328 16.1. second stage. */
void
ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link,
- struct vertex *v, struct ospf_area *area)
+ struct vertex *v, struct ospf_area *area,
+ int parent_is_root)
{
u_int32_t cost;
struct route_node *rn;
@@ -514,7 +515,20 @@ ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d",
v->distance, ntohs(link->m[0].metric), cost);
-
+
+ /* PtP links with /32 masks adds host routes to remote, directly
+ * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
+ * Such routes can just be ignored for the sake of tidyness.
+ */
+ if (parent_is_root && link->link_data.s_addr == 0xffffffff &&
+ ospf_if_lookup_by_local_addr (area->ospf, NULL, link->link_id))
+ {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug ("%s: ignoring host route %s/32 to self.",
+ __func__, inet_ntoa (link->link_id));
+ return;
+ }
+
rn = route_node_get (rt, (struct prefix *) &p);
/* Lookup current routing table. */
diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h
index 351e014d..0d37436d 100644
--- a/ospfd/ospf_route.h
+++ b/ospfd/ospf_route.h
@@ -140,7 +140,8 @@ extern void ospf_intra_add_transit (struct route_table *, struct vertex *,
extern void ospf_intra_add_stub (struct route_table *,
struct router_lsa_link *, struct vertex *,
- struct ospf_area *);
+ struct ospf_area *,
+ int parent_is_root);
extern int ospf_route_cmp (struct ospf *, struct ospf_route *,
struct ospf_route *);
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 6e972605..e6ce1f01 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -27,10 +27,12 @@
#ifdef HAVE_SNMP
#ifdef HAVE_NETSNMP
#include <net-snmp/net-snmp-config.h>
-#endif
+#include <net-snmp/net-snmp-includes.h>
+#else
#include <asn1.h>
#include <snmp.h>
#include <snmp_impl.h>
+#endif
#include "if.h"
#include "log.h"
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 23d45dd6..82f0fedd 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -946,7 +946,8 @@ ospf_spf_dump (struct vertex *v, int i)
/* Second stage of SPF calculation. */
static void
ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
- struct route_table *rt)
+ struct route_table *rt,
+ int parent_is_root)
{
struct listnode *cnode, *cnnode;
struct vertex *child;
@@ -981,7 +982,7 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
(l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
if (l->m[0].type == LSA_LINK_TYPE_STUB)
- ospf_intra_add_stub (rt, l, v, area);
+ ospf_intra_add_stub (rt, l, v, area, parent_is_root);
}
}
@@ -991,8 +992,17 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
{
if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))
continue;
-
- ospf_spf_process_stubs (area, child, rt);
+
+ /* the first level of routers connected to the root
+ * should have 'parent_is_root' set, including those
+ * connected via a network vertex.
+ */
+ if (area->spf == v)
+ parent_is_root = 1;
+ else if (v->type == OSPF_VERTEX_ROUTER)
+ parent_is_root = 0;
+
+ ospf_spf_process_stubs (area, child, rt, parent_is_root);
SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);
}
@@ -1179,7 +1189,7 @@ ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table,
}
/* Second stage of SPF calculation procedure's */
- ospf_spf_process_stubs (area, area->spf, new_table);
+ ospf_spf_process_stubs (area, area->spf, new_table, 0);
/* Free candidate queue. */
pqueue_delete (candidate);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 5307b413..11f12c5c 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3093,7 +3093,7 @@ DEFUN (show_ip_ospf_neighbor_all,
"Neighbor list\n"
"include down status neighbor\n")
{
- struct ospf *ospf = vty->index;
+ struct ospf *ospf = ospf_lookup ();
struct listnode *node;
struct ospf_interface *oi;
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index f302d28d..e27f1394 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -87,7 +87,6 @@ static int
ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
{
struct interface *ifp;
- struct ospf *ospf;
ifp = zebra_interface_add_read (zclient->ibuf);
@@ -103,9 +102,7 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
}
- ospf = ospf_lookup ();
- if (ospf != NULL)
- ospf_if_update (ospf);
+ ospf_if_update (NULL, ifp);
#ifdef HAVE_SNMP
ospf_snmp_if_update (ifp);
@@ -255,7 +252,6 @@ static int
ospf_interface_address_add (int command, struct zclient *zclient,
zebra_size_t length)
{
- struct ospf *ospf;
struct connected *c;
c = zebra_interface_address_read (command, zclient->ibuf);
@@ -270,9 +266,7 @@ ospf_interface_address_add (int command, struct zclient *zclient,
zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
}
- ospf = ospf_lookup ();
- if (ospf != NULL)
- ospf_if_update (ospf);
+ ospf_if_update (NULL, c->ifp);
#ifdef HAVE_SNMP
ospf_snmp_if_update (c->ifp);
@@ -285,7 +279,6 @@ static int
ospf_interface_address_delete (int command, struct zclient *zclient,
zebra_size_t length)
{
- struct ospf *ospf;
struct connected *c;
struct interface *ifp;
struct ospf_interface *oi;
@@ -327,10 +320,6 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
connected_free (c);
- ospf = ospf_lookup ();
- if (ospf != NULL)
- ospf_if_update (ospf);
-
return 0;
}
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index a4c4fac3..32580ccf 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -68,7 +68,9 @@ extern struct in_addr router_id_zebra;
static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
static void ospf_network_free (struct ospf *, struct ospf_network *);
static void ospf_area_free (struct ospf_area *);
-static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
+static void ospf_network_run (struct prefix *, struct ospf_area *);
+static void ospf_network_run_interface (struct prefix *, struct ospf_area *,
+ struct interface *);
static void ospf_finish_final (struct ospf *);
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
@@ -78,6 +80,7 @@ ospf_router_id_update (struct ospf *ospf)
{
struct in_addr router_id, router_id_old;
struct ospf_interface *oi;
+ struct interface *ifp;
struct listnode *node;
if (IS_DEBUG_OSPF_EVENT)
@@ -130,7 +133,8 @@ ospf_router_id_update (struct ospf *ospf)
ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
/* update ospf_interface's */
- ospf_if_update (ospf);
+ for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
+ ospf_if_update (ospf, ifp);
}
}
@@ -745,7 +749,7 @@ ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
area = ospf_area_get (ospf, area_id, ret);
/* Run network config now. */
- ospf_network_run (ospf, (struct prefix *)p, area);
+ ospf_network_run ((struct prefix *)p, area);
/* Update connected redistribute. */
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -770,6 +774,8 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
struct route_node *rn;
struct ospf_network *network;
struct external_info *ei;
+ struct listnode *node, *nnode;
+ struct ospf_interface *oi;
rn = route_node_lookup (ospf->networks, (struct prefix *)p);
if (rn == NULL)
@@ -783,7 +789,31 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
rn->info = NULL;
route_unlock_node (rn);
- ospf_if_update (ospf);
+ /* Find interfaces that not configured already. */
+ for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
+ {
+ int found = 0;
+ struct connected *co = oi->connected;
+
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ continue;
+
+ for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+ {
+ if (rn->info == NULL)
+ continue;
+
+ if (ospf_network_match_iface(co,&rn->p))
+ {
+ found = 1;
+ route_unlock_node (rn);
+ break;
+ }
+ }
+
+ if (found == 0)
+ ospf_if_free (oi);
+ }
/* Update connected redistribute. */
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -857,73 +887,78 @@ ospf_network_match_iface(struct connected *co, struct prefix *net)
}
void
-ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
+ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
+ struct interface *ifp)
{
- struct interface *ifp;
+ struct listnode *cnode;
struct connected *co;
+
+ if (memcmp (ifp->name, "VLINK", 5) == 0)
+ return;
+
+ /* if interface prefix is match specified prefix,
+ then create socket and join multicast group. */
+ for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
+ {
+ struct prefix *addr;
+
+ if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
+ continue;
+
+ addr = CONNECTED_ID(co);
+
+ if (p->family == co->address->family
+ && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4))
+ && ospf_network_match_iface(co,p))
+ {
+ struct ospf_interface *oi;
+
+ oi = ospf_if_new (area->ospf, ifp, co->address);
+ oi->connected = co;
+
+ oi->area = area;
+
+ oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
+ oi->output_cost = ospf_if_get_output_cost (oi);
+
+ /* Add pseudo neighbor. */
+ ospf_nbr_add_self (oi);
+
+ /* Relate ospf interface to ospf instance. */
+ oi->ospf = area->ospf;
+
+ /* update network type as interface flag */
+ /* If network type is specified previously,
+ skip network type setting. */
+ oi->type = IF_DEF_PARAMS (ifp)->type;
+
+ ospf_area_add_if (oi->area, oi);
+
+ /* if router_id is not configured, dont bring up
+ * interfaces.
+ * ospf_router_id_update() will call ospf_if_update
+ * whenever r-id is configured instead.
+ */
+ if ((area->ospf->router_id.s_addr != 0)
+ && if_is_operative (ifp))
+ ospf_if_up (oi);
+ }
+ }
+}
+
+void
+ospf_network_run (struct prefix *p, struct ospf_area *area)
+{
+ struct interface *ifp;
struct listnode *node;
/* Schedule Router ID Update. */
- if (ospf->router_id.s_addr == 0)
- ospf_router_id_update (ospf);
+ if (area->ospf->router_id.s_addr == 0)
+ ospf_router_id_update (area->ospf);
/* Get target interface. */
for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
- {
- struct listnode *cnode;
-
- if (memcmp (ifp->name, "VLINK", 5) == 0)
- continue;
-
- /* if interface prefix is match specified prefix,
- then create socket and join multicast group. */
- for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
- {
- struct prefix *addr;
-
- if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
- continue;
-
- addr = CONNECTED_ID(co);
-
- if (p->family == co->address->family
- && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
- && ospf_network_match_iface(co,p))
- {
- struct ospf_interface *oi;
-
- oi = ospf_if_new (ospf, ifp, co->address);
- oi->connected = co;
-
- oi->area = area;
-
- oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
- oi->output_cost = ospf_if_get_output_cost (oi);
-
- /* Add pseudo neighbor. */
- ospf_nbr_add_self (oi);
-
- /* Relate ospf interface to ospf instance. */
- oi->ospf = ospf;
-
- /* update network type as interface flag */
- /* If network type is specified previously,
- skip network type setting. */
- oi->type = IF_DEF_PARAMS (ifp)->type;
-
- ospf_area_add_if (oi->area, oi);
-
- /* if router_id is not configured, dont bring up
- * interfaces.
- * ospf_router_id_update() will call ospf_if_update
- * whenever r-id is configured instead.
- */
- if ((ospf->router_id.s_addr != 0)
- && if_is_operative (ifp))
- ospf_if_up (oi);
- }
- }
- }
+ ospf_network_run_interface (p, area, ifp);
}
void
@@ -954,55 +989,27 @@ ospf_ls_upd_queue_empty (struct ospf_interface *oi)
}
void
-ospf_if_update (struct ospf *ospf)
+ospf_if_update (struct ospf *ospf, struct interface *ifp)
{
struct route_node *rn;
- struct listnode *node, *nnode;
struct ospf_network *network;
struct ospf_area *area;
- struct ospf_interface *oi;
+
+ if (!ospf)
+ ospf = ospf_lookup ();
- if (ospf != NULL)
- {
- /* Router-ID must be configured. */
- if (ospf->router_id.s_addr == 0)
- return;
-
- /* Find interfaces that not configured already. */
- for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
- {
- int found = 0;
- struct connected *co = oi->connected;
-
- if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
- continue;
-
- for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
- {
- if (rn->info == NULL)
- continue;
-
- if (ospf_network_match_iface(co,&rn->p))
- {
- found = 1;
- route_unlock_node (rn);
- break;
- }
- }
-
- if (found == 0)
- ospf_if_free (oi);
- }
-
- /* Run each interface. */
- for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
- if (rn->info != NULL)
- {
- network = (struct ospf_network *) rn->info;
- area = ospf_area_get (ospf, network->area_id, network->format);
- ospf_network_run (ospf, &rn->p, area);
- }
- }
+ /* Router-ID must be configured. */
+ if (ospf->router_id.s_addr == 0)
+ return;
+
+ /* Run each netowrk for this interface. */
+ for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+ if (rn->info != NULL)
+ {
+ network = (struct ospf_network *) rn->info;
+ area = ospf_area_get (ospf, network->area_id, network->format);
+ ospf_network_run_interface (&rn->p, area, ifp);
+ }
}
void
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index b6187111..6a60e86f 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -588,7 +588,7 @@ extern int ospf_nbr_nbma_poll_interval_set (struct ospf *, struct in_addr,
extern int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr);
extern void ospf_prefix_list_update (struct prefix_list *);
extern void ospf_init (void);
-extern void ospf_if_update (struct ospf *);
+extern void ospf_if_update (struct ospf *, struct interface *);
extern void ospf_ls_upd_queue_empty (struct ospf_interface *);
extern void ospf_terminate (void);
extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *);