summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-12-02 08:55:11 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-12-02 09:01:32 -0800
commit48cebef94720702dcb750e0c8a8234387beecb12 (patch)
tree119eea096eb48fd1964ea1daef201e3cad6ec2c8
parent255495581f4bcc5289759197e5aa160462d64709 (diff)
downloadquagga-48cebef94720702dcb750e0c8a8234387beecb12.tar.bz2
quagga-48cebef94720702dcb750e0c8a8234387beecb12.tar.xz
Remember protocol as well as scope in RIB
This addresses potential issues with link management when multiple routing protocols are in use. Also fix non-linux build issues
-rw-r--r--zebra/connected.c5
-rw-r--r--zebra/kernel_socket.c2
-rw-r--r--zebra/rib.h14
-rw-r--r--zebra/rt_netlink.c39
-rw-r--r--zebra/rtread_getmsg.c2
-rw-r--r--zebra/rtread_proc.c3
-rw-r--r--zebra/zebra_rib.c6
7 files changed, 34 insertions, 37 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index b235d8c0..98c1ae19 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -191,7 +191,8 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
return;
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, &src,
- ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, RT_SCOPE_LINK);
+ ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0,
+ RT_SCOPE_LINK, RTPROT_KERNEL);
rib_update ();
}
@@ -274,7 +275,7 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
/* nothing to do? */
ifc = connected_implicit_withdraw (ifp, ifc);
connected_announce (ifp, ifc);
-
+
return ifc;
}
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index e77b9b78..045e42cb 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -898,7 +898,7 @@ rtm_read (struct rt_msghdr *rtm)
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
- &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0);
+ &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, 0, 0);
else
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
&p, &gate.sin.sin_addr, 0, 0);
diff --git a/zebra/rib.h b/zebra/rib.h
index c39afa73..c71407e4 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -55,14 +55,17 @@ struct rib
u_int32_t metric;
/* Which routing table */
- u_int32_t table;
+ u_int32_t table;
/* Type for this route. < ZEBRA_ROUTE_MAX */
u_int8_t type;
- /* Scope for this route. */
+ /* Scope for this route: RTM_UNIVERSE .. RTM_NOWHERE */
u_int8_t scope;
+ /* Routing protocol: RTPROT_UNSPEC .. */
+ u_int8_t protocol;
+
/* Status Flags for the *route_node*, but kept in the head RIB.. */
u_char rn_status;
#define RIB_ROUTE_QUEUED(x) (1 << (x))
@@ -109,7 +112,7 @@ struct static_ipv4
struct static_ipv4 *next;
/* Nexthop value. */
- union
+ union
{
struct in_addr ipv4;
char *ifname;
@@ -225,7 +228,7 @@ struct vrf
struct route_table *stable[AFI_MAX][SAFI_MAX];
};
-extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int,
+extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int,
struct in_addr *);
extern struct nexthop *nexthop_ifname_add (struct rib *, char *);
extern struct nexthop *nexthop_blackhole_add (struct rib *);
@@ -255,7 +258,8 @@ extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t i
extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, struct in_addr *src,
unsigned int ifindex, u_int32_t vrf_id,
- u_int32_t metric, u_int8_t distance, u_int8_t scope);
+ u_int32_t metric, u_int8_t distance,
+ u_int8_t scope, u_int8_t protocol);
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *);
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 8f8ad58a..e4ce5acc 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -41,7 +41,6 @@
#include "zebra/redistribute.h"
#include "zebra/interface.h"
#include "zebra/debug.h"
-#include <stddef.h>
/* Socket interface to kernel */
struct nlsock
@@ -66,7 +65,7 @@ static const struct message nlmsg_str[] = {
{0, NULL}
};
-static const char *nexthop_types_desc[] =
+static const char *nexthop_types_desc[] =
{
"none",
"Directly connected",
@@ -260,7 +259,6 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
while (1)
{
- //increased from 4096 to 32768 as recvmsg overrun error
char buf[32768];
struct iovec iov = { buf, sizeof buf };
struct sockaddr_nl snl;
@@ -274,7 +272,6 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
continue;
if (errno == EWOULDBLOCK || errno == EAGAIN)
break;
-
zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
nl->name, safe_strerror(errno));
continue;
@@ -293,13 +290,6 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
return -1;
}
- /* JF: Ignore messages that aren't from the kernel */
- if ( snl.nl_pid != 0 )
- {
- zlog_debug ("Ignoring message from pid %u", snl.nl_pid );
- continue;
- }
-
for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
h = NLMSG_NEXT (h, status))
{
@@ -701,6 +691,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
return 0;
if (rtm->rtm_protocol == RTPROT_REDIRECT)
return 0;
+
if (rtm->rtm_protocol == RTPROT_KERNEL)
return 0;
@@ -743,7 +734,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
p.prefixlen = rtm->rtm_dst_len;
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
- table, metric, 0, rtm->rtm_scope);
+ table, metric, 0, rtm->rtm_scope, rtm->rtm_protocol);
}
#ifdef HAVE_IPV6
if (rtm->rtm_family == AF_INET6)
@@ -882,7 +873,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
if (h->nlmsg_type == RTM_NEWROUTE)
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0,
- 0, rtm->rtm_scope);
+ 0, rtm->rtm_scope, rtm->rtm_protocol);
else
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
}
@@ -970,7 +961,6 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
unsigned int mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
ifp = if_lookup_by_index (ifi->ifi_index);
- /* New interface */
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
{
if (ifp == NULL)
@@ -987,11 +977,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
zlog_info ("interface %s index %d %s added.",
name, ifi->ifi_index, if_flag_dump(new_flags));
+
ifp->flags = new_flags;
ifp->mtu6 = ifp->mtu = mtu;
- /* If new link is added. */
- if_add_update (ifp);
+ /* If new link is added. */
+ if_add_update (ifp);
}
/* Interface status change. */
else if (new_flags != ifp->flags)
@@ -1030,8 +1021,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
/* Interface mtu change */
else if (mtu != ifp->mtu)
{
- zlog_info("interface index %d mtu changed from %u to %u",
- ifp->mtu, mtu);
+ zlog_info("interface %s mtu changed from %u to %u",
+ ifp->name, ifp->mtu, mtu);
ifp->mtu = ifp->mtu6 = mtu;
if (if_is_operative (ifp))
zebra_interface_up_update (ifp);
@@ -1054,6 +1045,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
if_delete_update (ifp);
if_delete (ifp);
}
+
return 0;
}
@@ -1288,9 +1280,10 @@ netlink_delroute (int family, void *dest, int length, void *gate,
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_DELROUTE;
req.r.rtm_family = family;
+ req.r.rtm_dst_len = length;
req.r.rtm_scope = RT_SCOPE_NOWHERE;
+ req.r.rtm_protocol = RTPROT_UNSPEC;
req.r.rtm_table = table;
- req.r.rtm_dst_len = length;
if (dest)
addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
@@ -1333,8 +1326,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
req.r.rtm_family = family;
req.r.rtm_table = rib->table;
req.r.rtm_dst_len = p->prefixlen;
- req.r.rtm_protocol = RTPROT_ZEBRA;
- req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+ req.r.rtm_scope = rib->scope;
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
discard = 1;
@@ -1343,8 +1335,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
switch (rib->type) {
case ZEBRA_ROUTE_KERNEL:
- /* FIXME: should remember original protocol from RTM_NEWLINK */
- req.r.rtm_protocol = RTPROT_BOOT;
+ req.r.rtm_protocol = rib->protocol;
break;
case ZEBRA_ROUTE_CONNECT:
req.r.rtm_protocol = RTPROT_KERNEL;
@@ -1353,8 +1344,6 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
req.r.rtm_protocol = RTPROT_ZEBRA;
}
- req.r.rtm_scope = rib->scope;
-
if (cmd == RTM_NEWROUTE)
{
if (discard)
diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c
index 3e065c6f..2978ae11 100644
--- a/zebra/rtread_getmsg.c
+++ b/zebra/rtread_getmsg.c
@@ -90,7 +90,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
gateway.s_addr = routeEntry->ipRouteNextHop;
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &prefix,
- &gateway, NULL, 0, 0, 0, 0);
+ &gateway, NULL, 0, 0, 0, 0, 0, 0);
}
void
diff --git a/zebra/rtread_proc.c b/zebra/rtread_proc.c
index 1de435a4..4f246de9 100644
--- a/zebra/rtread_proc.c
+++ b/zebra/rtread_proc.c
@@ -96,7 +96,8 @@ proc_route_read (void)
p.prefixlen = ip_masklen (tmpmask);
sscanf (gate, "%lX", (unsigned long *)&gateway);
- rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0);
+ rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, NULL,
+ 0, 0, 0, 0, 0, 0);
}
fclose (fp);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 69249779..0e9e8a26 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1623,7 +1623,8 @@ int
rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, struct in_addr *src,
unsigned int ifindex, u_int32_t vrf_id,
- u_int32_t metric, u_int8_t distance, u_int8_t scope)
+ u_int32_t metric, u_int8_t distance,
+ u_int8_t scope, u_int8_t proto)
{
struct rib *rib;
struct rib *same = NULL;
@@ -1688,6 +1689,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
rib->nexthop_num = 0;
rib->uptime = time (NULL);
rib->scope = scope;
+ rib->protocol = proto;
/* Nexthop settings. */
if (gate)
@@ -1701,7 +1703,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
nexthop_ifindex_add (rib, ifindex, src);
/* If this route is kernel route, set FIB flag to the route. */
- if (RIB_SYSTEM_ROUTE (rib))
+ if (RIB_SYSTEM_ROUTE (rib))
{
/* Mark system routes with the don't touch me flag */
if (! rib_system_routes)