diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-12-02 08:55:11 -0800 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-12-02 09:01:32 -0800 |
commit | 48cebef94720702dcb750e0c8a8234387beecb12 (patch) | |
tree | 119eea096eb48fd1964ea1daef201e3cad6ec2c8 | |
parent | 255495581f4bcc5289759197e5aa160462d64709 (diff) | |
download | quagga-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.c | 5 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 2 | ||||
-rw-r--r-- | zebra/rib.h | 14 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 39 | ||||
-rw-r--r-- | zebra/rtread_getmsg.c | 2 | ||||
-rw-r--r-- | zebra/rtread_proc.c | 3 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 6 |
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) |