ospfd: use ZEBRA_NEXTHOP_IPV4_IFINDEX

OSPF really needs to specify interface in its routes. Otherwise
ospf may change the wrong route.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
[fixed up some whitespace errors, split patch in two]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
Joakim Tjernlund 2012-07-07 17:06:13 +02:00 committed by David Lamparter
parent c963c20346
commit ba281d3d04

View File

@ -371,7 +371,14 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
/* Nexthop, ifindex, distance and metric information. */ /* Nexthop, ifindex, distance and metric information. */
for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
{ {
if (path->nexthop.s_addr != INADDR_ANY) 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_putc (s, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (s, &path->nexthop); stream_put_in_addr (s, &path->nexthop);
@ -418,60 +425,87 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
void void
ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or) ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
{ {
struct zapi_ipv4 api; u_char message;
u_char distance;
u_char flags;
int psize;
struct stream *s;
struct ospf_path *path; struct ospf_path *path;
struct in_addr *nexthop; struct listnode *node;
struct listnode *node, *nnode;
if (zclient->redist[ZEBRA_ROUTE_OSPF]) if (zclient->redist[ZEBRA_ROUTE_OSPF])
{ {
api.type = ZEBRA_ROUTE_OSPF; message = 0;
api.flags = 0; flags = 0;
api.message = 0; /* Distance value. */
api.safi = SAFI_UNICAST; distance = ospf_distance_apply (p, or);
api.ifindex_num = 0; /* Make packet. */
api.nexthop_num = 0; s = zclient->obuf;
stream_reset (s);
for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path)) /* Put command, type, flags, message. */
{ zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
if (path->nexthop.s_addr != INADDR_ANY) stream_putc (s, ZEBRA_ROUTE_OSPF);
{ stream_putc (s, flags);
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); stream_putc (s, message);
api.nexthop_num = 1; stream_putw (s, SAFI_UNICAST);
nexthop = &path->nexthop;
api.nexthop = &nexthop;
}
else if (if_lookup_by_index(path->ifindex))
{
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
api.ifindex_num = 1;
api.ifindex = &path->ifindex;
}
else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
{
zlog_debug("Zebra: no ifp %s %d",
inet_ntoa(p->prefix),
p->prefixlen);
}
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); /* Put prefix information. */
psize = PSIZE (p->prefixlen);
stream_putc (s, p->prefixlen);
stream_write (s, (u_char *) & p->prefix, psize);
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num) /* Nexthop count. */
{ stream_putc (s, or->paths->count);
/* 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);
stream_putl (s, path->ifindex);
}
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
{
char buf[2][INET_ADDRSTRLEN]; char buf[2][INET_ADDRSTRLEN];
zlog_debug("Zebra: Route delete %s/%d nexthop %s", zlog_debug("Zebra: Route add %s/%d nexthop %s",
inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])), inet_ntop(AF_INET, &p->prefix,
buf[0], sizeof(buf[0])),
p->prefixlen, p->prefixlen,
inet_ntop(AF_INET, *api.nexthop, inet_ntop(AF_INET, &path->nexthop,
buf[1], sizeof(buf[1]))); buf[1], sizeof(buf[1])));
} }
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num) }
{
zlog_debug ("Zebra: Route delete %s/%d ifindex %d", if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
inet_ntoa (p->prefix), stream_putc (s, distance);
p->prefixlen, *api.ifindex); if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
} {
} if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
stream_putl (s, or->cost + or->u.ext.type2_cost);
else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
stream_putl (s, or->u.ext.type2_cost);
else
stream_putl (s, or->cost);
}
stream_putw_at (s, 0, stream_get_endp (s));
zclient_send_message(zclient);
} }
} }