1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-23 00:43:28 +00:00

- Update to 0.99.9 + patches from quagga CVS

Approved by:	maintainer
This commit is contained in:
Sergey Matveychuk 2007-09-24 07:59:16 +00:00
parent 4b0a02d453
commit b7d737ee9d
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=200029
17 changed files with 470 additions and 1324 deletions

View File

@ -6,8 +6,7 @@
#
PORTNAME= quagga
PORTVERSION= 0.99.8
PORTREVISION= 2
PORTVERSION= 0.99.9
CATEGORIES= net ipv6
MASTER_SITES= http://quagga.net/download/ \
http://www.ru.quagga.net/download/ \
@ -40,7 +39,8 @@ OPTIONS= ISISD "Enable experimental ISIS daemon" off \
RTADV "IPv6 Router Advertisements" off \
SNMP "SNMP support" off \
TCPSOCKETS "Use TCP/IP sockets for protocol daemons" off \
TCPMD5 "Use experimental MD5 patch for BGP" off
TCPMD5 "Use experimental MD5 patch for BGP" off \
DLMALLOC "Use dlmalloc (much faster)" off
.include <bsd.port.pre.mk>
@ -113,13 +113,15 @@ LIB_DEPENDS+=netsnmp.10:${PORTSDIR}/net-mgmt/net-snmp
.endif
.if defined(WITH_TCPMD5)
.if ${OSVERSION} < 491000
BROKEN= This version of FreeBSD does not have TCP MD5 signature support
.endif
EXTRA_PATCHES+=${PATCHDIR}/extra-tcpmd5-patch-bgpd-bgp_network.c ${PATCHDIR}/extra-tcpmd5-patch-bgpd-bgp_vty.c ${PATCHDIR}/extra-tcpmd5-patch-bgpd-bgpd.c ${PATCHDIR}/extra-tcpmd5-patch-bgpd-bgpd.h ${PATCHDIR}/extra-tcpmd5-patch-lib-sockopt.c ${PATCHDIR}/extra-tcpmd5-patch-lib-sockopt.h ${PATCHDIR}/extra-tcpmd5-patch-vtysh-extract.pl.in
CFLAGS+= -DQUAGGA_TCP_MD5SIG
.endif
.if defined(WITH_DLMALLOC)
LIB_DEPENDS+=dlmalloc.2:${PORTSDIR}/devel/libdlmalloc
LDFLAGS+=-ldlmalloc
.endif
.if ${OSVERSION} < 600000
BUILD_DEPENDS+=${LOCALBASE}/bin/makeinfo:${PORTSDIR}/print/texinfo
CONFIGURE_ENV+=MAKEINFO=${LOCALBASE}/bin/makeinfo
@ -159,6 +161,7 @@ pre-everything::
@${ECHO} " WITH_SNMP SNMP support"
@${ECHO} " WITH_TCPSOCKETS Use TCP/IP sockets for protocol daemons"
@${ECHO} " WITH_TCPMD5 Use experimental MD5 patch for BGP"
@${ECHO} " WITH_DLMALLOC Use dlmalloc (much faster)"
post-install:
@${SETENV} ${SCRIPTS_ENV} ${SH} ${PKGINSTALL} ${PKGNAME} POST-INSTALL
@ -192,16 +195,6 @@ post-install:
@${ECHO} " device cryptodev"
@${ECHO} ""
.endif
.if ${OSVERSION} < 500000
@${ECHO} "Warning: You are running 4.x version of FreeBSD. To properly start"
@${ECHO} " quagga on your system please rename"
@${ECHO} " ${PREFIX}/etc/rc.d/quagga.sh to something like"
@${ECHO} " ${PREFIX}/etc/rc.d/010.quagga.sh or even You"
@${ECHO} " should write your own startup script and use it with"
@${ECHO} " router_enable=\"YES\""
@${ECHO} " router=\"your_startup_script_here\" in your rc.conf"
@${ECHO} ""
.endif
.if !defined(BATCH)
post-clean:

View File

@ -1,3 +1,3 @@
MD5 (quagga-0.99.8.tar.gz) = 0a53fb579033fa57ca0e5c3ff0b52105
SHA256 (quagga-0.99.8.tar.gz) = 7e745118921982ad7f67a6733161f74c88ba71c587158ab335f0581124be551d
SIZE (quagga-0.99.8.tar.gz) = 2322571
MD5 (quagga-0.99.9.tar.gz) = 4dbdaf91bf6609803819d97d5fccc4c9
SHA256 (quagga-0.99.9.tar.gz) = 92abf44c5239c8a18762cf27cafd03b46d581f180bc411706314b8b8d1e94db0
SIZE (quagga-0.99.9.tar.gz) = 2341067

View File

@ -0,0 +1,198 @@
diff --git bgpd/bgp_open.c bgpd/bgp_open.c
index d4f7cdf..cd23577 100644
--- bgpd/bgp_open.c
+++ bgpd/bgp_open.c
@@ -177,7 +177,7 @@ bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
peer->afc_recv[mpc.afi][mpc.safi] = 1;
if (peer->afc[mpc.afi][mpc.safi])
- peer->afc_nego[mpc.safi][mpc.safi] = 1;
+ peer->afc_nego[mpc.afi][mpc.safi] = 1;
else
return -1;
diff --git bgpd/bgpd.c bgpd/bgpd.c
diff --git tests/bgp_capability_test.c tests/bgp_capability_test.c
index 5595ecf..4729f5c 100644
--- tests/bgp_capability_test.c
+++ tests/bgp_capability_test.c
@@ -27,6 +27,14 @@ static struct test_segment {
#define SHOULD_PARSE 0
#define SHOULD_ERR -1
int parses; /* whether it should parse or not */
+
+ /* AFI/SAFI validation */
+ int validate_afi;
+ afi_t afi;
+ safi_t safi;
+#define VALID_AFI 1
+#define INVALID_AFI 0
+ int afi_valid;
} test_segments [] =
{
/* 0 */
@@ -53,47 +61,63 @@ static struct test_segment {
{ CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
4, SHOULD_ERR,
},
- /* 4 */
- { "MP1",
+ { NULL, NULL, {0}, 0, 0},
+};
+
+static struct test_segment mp_segments[] =
+{
+ { "MP4",
"MP IP/Uni",
{ 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
- 6, SHOULD_PARSE,
+ 6, SHOULD_PARSE, AFI_IP, SAFI_UNICAST,
+ },
+ { "MPv6",
+ "MP IPv6/Uni",
+ { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
+ 6, SHOULD_PARSE,
+ 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
},
/* 5 */
{ "MP2",
"MP IP/Multicast",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
- 6, SHOULD_PARSE,
+ 6, SHOULD_PARSE,
+ 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
},
/* 6 */
{ "MP3",
"MP IP6/VPNv4",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
6, SHOULD_PARSE, /* parses, but invalid afi,safi */
+ 1, AFI_IP6, BGP_SAFI_VPNV4, INVALID_AFI,
},
/* 7 */
{ "MP5",
"MP IP6/MPLS-VPN",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
- 6, SHOULD_PARSE,
+ 6, SHOULD_PARSE,
+ 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
},
/* 8 */
{ "MP6",
"MP IP4/VPNv4",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
- 6, SHOULD_PARSE,
+ 6, SHOULD_PARSE,
+ 1, AFI_IP, BGP_SAFI_VPNV4, VALID_AFI,
},
/* 9 */
{ "MP7",
"MP IP4/VPNv6",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x81 },
- 6, SHOULD_PARSE, /* parses, but invalid afi,safi tuple! - manually inspect */
+ 6, SHOULD_PARSE, /* parses, but invalid afi,safi tuple */
+ 1, AFI_IP, BGP_SAFI_VPNV6, INVALID_AFI,
},
/* 10 */
{ "MP8",
"MP unknown AFI",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
- 6, SHOULD_PARSE, /* parses, but unknown */
+ 6, SHOULD_PARSE,
+ 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
},
/* 11 */
{ "MP-short",
@@ -106,7 +130,13 @@ static struct test_segment {
"MP IP4/Unicast, length too long",
{ CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
6, SHOULD_ERR,
+ 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
},
+ { NULL, NULL, {0}, 0, 0}
+};
+
+static struct test_segment misc_segments[] =
+{
/* 13 */
{ "ORF",
"ORF, simple, single entry, single tuple",
@@ -366,6 +396,7 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
{
int ret;
int capability = 0;
+ int oldfailed = failed;
stream_reset (peer->ibuf);
switch (type)
@@ -398,16 +429,34 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
exit(1);
}
- printf ("parsed?: %s\n", ret ? "no" : "yes");
-
- if (ret == t->parses)
- printf ("OK\n");
- else
+ if (!ret && t->validate_afi)
{
- printf ("failed\n");
- failed++;
+ safi_t safi = t->safi;
+
+ if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
+ failed++;
+
+ printf ("MP: %u/%u (%u): recv %u, nego %u\n",
+ t->afi, t->safi, safi,
+ peer->afc_recv[t->afi][safi],
+ peer->afc_nego[t->afi][safi]);
+
+ if (t->afi_valid == VALID_AFI)
+ {
+
+ if (!peer->afc_recv[t->afi][safi])
+ failed++;
+ if (!peer->afc_nego[t->afi][safi])
+ failed++;
+ }
}
+ printf ("parsed?: %s\n", ret ? "no" : "yes");
+
+ if (ret != t->parses)
+ failed++;
+
+ printf ("%s\n", (failed > oldfailed) ? "failed!" : "OK");
printf ("\n");
}
@@ -439,12 +488,26 @@ main (void)
for (i = AFI_IP; i < AFI_MAX; i++)
for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
- peer->afc_nego[i][j] = 1;
+ {
+ peer->afc[i][j] = 1;
+ peer->afc_adv[i][j] = 1;
+ }
- i =0;
+ i = 0;
+ while (mp_segments[i].name)
+ parse_test (peer, &mp_segments[i++], OPEN);
+
+ /* These tests assume mp_segments tests set at least
+ * one of the afc_nego's
+ */
+ i = 0;
while (test_segments[i].name)
parse_test (peer, &test_segments[i++], OPEN);
+ i = 0;
+ while (misc_segments[i].name)
+ parse_test (peer, &misc_segments[i++], OPEN);
+
SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
peer->status = Established;

View File

@ -1,210 +0,0 @@
--- bgpd/ChangeLog.orig 23 Aug 2007 23:22:02 -0000 1.140
+++ bgpd/ChangeLog 27 Aug 2007 11:48:47 -0000
@@ -1,3 +1,24 @@
+2007-08-27 Paul Jakma <paul.jakma@sun.com>
+
+ * bgp_route.c: (bgp_announce_check) Fix bug #398, slight
+ modification of Vladimir Ivanov's suggested fix - to keep
+ memory alloc conditional.
+ (bgp_process_announce_selected) Don't take struct attr as
+ argument, none of the callers need it and it needlessly
+ distances allocation from use.
+ Free the extended attr, the attr itself is on the stack.
+ Fix bad indentation.
+ * bgp_attr.c: (bgp_packet_attribute) Remove incorrect assert,
+ and adjust conditional to test attr->extra, diagnosis by
+ Vladimir Ivanov in bug #398.
+
+2007-08-27 Vladimir Ivanov <wawa@yandex-team.ru>
+
+ * bgp_route.c: (bgp_announce_check_rsclient) copy of
+ ri->attr is no longer deep enough, due to addition of
+ attr->extra. It should use bgp_attr_dup, as
+ bgp_announce_check() does.
+
2007-08-23 Paul Jakma <paul.jakma@sun.com>
* bgp_regex.c: (bgp_regcomp) Pass NOSUB flag to regcomp to
--- bgpd/bgp_attr.c.orig 6 Aug 2007 15:24:51 -0000 1.22
+++ bgpd/bgp_attr.c 27 Aug 2007 11:48:47 -0000
@@ -1673,8 +1673,6 @@ bgp_packet_attribute (struct bgp *bgp, s
&& from
&& peer_sort (from) == BGP_PEER_IBGP)
{
- assert (attr->extra);
-
/* Originator ID. */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc (s, BGP_ATTR_ORIGINATOR_ID);
@@ -1689,7 +1687,7 @@ bgp_packet_attribute (struct bgp *bgp, s
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc (s, BGP_ATTR_CLUSTER_LIST);
- if (attr->extra->cluster)
+ if (attr->extra && attr->extra->cluster)
{
stream_putc (s, attr->extra->cluster->length + 4);
/* If this peer configuration's parent BGP has cluster_id. */
--- bgpd/bgp_route.c.orig 6 Aug 2007 15:24:51 -0000 1.63
+++ bgpd/bgp_route.c 27 Aug 2007 11:48:48 -0000
@@ -1045,20 +1045,18 @@ bgp_announce_check (struct bgp_info *ri,
|| (ri->extra && ri->extra->suppress) )
{
struct bgp_info info;
- struct attr dummy_attr;
+ struct attr dummy_attr = { 0 };
info.peer = peer;
info.attr = attr;
-
/* The route reflector is not allowed to modify the attributes
of the reflected IBGP routes. */
if (peer_sort (from) == BGP_PEER_IBGP
&& peer_sort (peer) == BGP_PEER_IBGP)
{
- dummy_attr.extra = NULL;
bgp_attr_dup (&dummy_attr, attr);
- info.attr = &dummy_attr;
+ info.attr = &dummy_attr;
}
SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
@@ -1070,7 +1068,8 @@ bgp_announce_check (struct bgp_info *ri,
peer->rmap_type = 0;
- bgp_attr_extra_free (&dummy_attr);
+ if (dummy_attr.extra)
+ bgp_attr_extra_free (&dummy_attr);
if (ret == RMAP_DENYMATCH)
{
@@ -1173,7 +1172,7 @@ bgp_announce_check_rsclient (struct bgp_
#endif /* BGP_SEND_ASPATH_CHECK */
/* For modify attribute, copy it to temporary structure. */
- *attr = *ri->attr;
+ bgp_attr_dup (attr, ri->attr);
/* next-hop-set */
if ((p->family == AF_INET && attr->nexthop.s_addr == 0)
@@ -1375,21 +1374,22 @@ bgp_best_selection (struct bgp *bgp, str
static int
bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
- struct bgp_node *rn, struct attr *attr, afi_t afi, safi_t safi)
- {
+ struct bgp_node *rn, afi_t afi, safi_t safi)
+{
struct prefix *p;
+ struct attr attr = { 0 };
p = &rn->p;
- /* Announce route to Established peer. */
- if (peer->status != Established)
+ /* Announce route to Established peer. */
+ if (peer->status != Established)
return 0;
- /* Address family configuration check. */
- if (! peer->afc_nego[afi][safi])
+ /* Address family configuration check. */
+ if (! peer->afc_nego[afi][safi])
return 0;
- /* First update is deferred until ORF or ROUTE-REFRESH is received */
+ /* First update is deferred until ORF or ROUTE-REFRESH is received */
if (CHECK_FLAG (peer->af_sflags[afi][safi],
PEER_STATUS_ORF_WAIT_REFRESH))
return 0;
@@ -1399,21 +1399,24 @@ bgp_process_announce_selected (struct pe
case BGP_TABLE_MAIN:
/* Announcement to peer->conf. If the route is filtered,
withdraw it. */
- if (selected && bgp_announce_check (selected, peer, p, attr, afi, safi))
- bgp_adj_out_set (rn, peer, p, attr, afi, safi, selected);
+ if (selected && bgp_announce_check (selected, peer, p, &attr, afi, safi))
+ bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
else
bgp_adj_out_unset (rn, peer, p, afi, safi);
break;
case BGP_TABLE_RSCLIENT:
/* Announcement to peer->conf. If the route is filtered,
withdraw it. */
- if (selected && bgp_announce_check_rsclient
- (selected, peer, p, attr, afi, safi))
- bgp_adj_out_set (rn, peer, p, attr, afi, safi, selected);
- else
- bgp_adj_out_unset (rn, peer, p, afi, safi);
+ if (selected &&
+ bgp_announce_check_rsclient (selected, peer, p, &attr, afi, safi))
+ bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
+ else
+ bgp_adj_out_unset (rn, peer, p, afi, safi);
break;
}
+
+ bgp_attr_extra_free (&attr);
+
return 0;
}
@@ -1463,8 +1466,7 @@ bgp_process_rsclient (struct work_queue
bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
}
- bgp_process_announce_selected (rsclient, new_select, rn, &attr,
- afi, safi);
+ bgp_process_announce_selected (rsclient, new_select, rn, afi, safi);
}
}
else
@@ -1476,8 +1478,7 @@ bgp_process_rsclient (struct work_queue
bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
}
- bgp_process_announce_selected (rsclient, new_select, rn,
- &attr, afi, safi);
+ bgp_process_announce_selected (rsclient, new_select, rn, afi, safi);
}
if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
@@ -1503,9 +1504,6 @@ bgp_process_main (struct work_queue *wq,
struct bgp_info_pair old_and_new;
struct listnode *node, *nnode;
struct peer *peer;
- struct attr attr;
-
- memset (&attr, 0, sizeof (struct attr));
/* Best path selection. */
bgp_best_selection (bgp, rn, &old_and_new);
@@ -1537,7 +1535,7 @@ bgp_process_main (struct work_queue *wq,
/* Check each BGP peer. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
- bgp_process_announce_selected (peer, new_select, rn, &attr, afi, safi);
+ bgp_process_announce_selected (peer, new_select, rn, afi, safi);
}
/* FIB update. */
@@ -1562,8 +1560,6 @@ bgp_process_main (struct work_queue *wq,
if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
bgp_info_reap (rn, old_select);
- bgp_attr_extra_free (&attr);
-
UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
return WQ_SUCCESS;
}
@@ -6214,7 +6210,7 @@ bgp_show_table (struct vty *vty, struct
{
struct route_map *rmap = output_arg;
struct bgp_info binfo;
- struct attr dummy_attr;
+ struct attr dummy_attr = { 0 };
int ret;
bgp_attr_dup (&dummy_attr, ri->attr);

View File

@ -0,0 +1,12 @@
--- zebra/rt_socket.c 13 Aug 2007 16:03:07 -0000 1.13
+++ zebra/rt_socket.c 12 Sep 2007 13:31:03 -0000
@@ -207,6 +207,9 @@
case ZEBRA_ERR_RTNOEXIST:
case ZEBRA_ERR_RTUNREACH:
default:
+ /* This point is reachable regardless of debugging mode. */
+ if (!IS_ZEBRA_DEBUG_RIB)
+ inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s",
__func__, prefix_buf, p->prefixlen, error, LOOKUP (rtm_type_str, cmd));
break;

View File

@ -1,46 +0,0 @@
--- zebra/rt_socket.c.orig 2007-05-10 00:59:35.000000000 +0400
+++ zebra/rt_socket.c 2007-07-31 15:58:18.000000000 +0400
@@ -99,9 +99,7 @@
if ((cmd == RTM_ADD
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|| (cmd == RTM_DELETE
-#if 0
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
-#endif
))
{
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
@@ -138,9 +136,6 @@
}
}
- if (cmd == RTM_ADD)
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
-
if (gate && p->prefixlen == 32)
mask = NULL;
else
@@ -152,7 +147,6 @@
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
mask = &sin_mask;
}
- }
error = rtm_write (cmd,
(union sockunion *)&sin_dest,
@@ -169,8 +163,13 @@
nexthop_num, error);
}
#endif
-
- nexthop_num++;
+ if (error == 0)
+ {
+ nexthop_num++;
+ if (cmd == RTM_ADD)
+ SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
+ }
}
/* If there is no useful nexthop then return. */

View File

@ -0,0 +1,108 @@
--- zebra/kernel_socket.c 21 Aug 2007 16:15:39 -0000 1.47
+++ zebra/kernel_socket.c 14 Sep 2007 09:55:16 -0000
@@ -160,7 +160,6 @@
#endif /* RTM_IFANNOUNCE */
{0, NULL}
};
-int rtm_type_str_max = sizeof (rtm_type_str) / sizeof (struct message) - 1;
struct message rtm_flag_str[] =
{
@@ -754,7 +753,7 @@
return;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: got rtm of type %d (%s)", __func__, rtm->rtm_type,
- LOOKUP (rtm_type_str, rtm->rtm_type));
+ lookup (rtm_type_str, rtm->rtm_type));
#ifdef RTF_CLONED /*bsdi, netbsd 1.6*/
if (flags & RTF_CLONED)
@@ -820,17 +819,17 @@
{
case ZEBRA_RIB_NOTFOUND:
zlog_debug ("%s: %s %s/%d: desync: RR isn't yet in RIB, while already in FIB",
- __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
break;
case ZEBRA_RIB_FOUND_CONNECTED:
case ZEBRA_RIB_FOUND_NOGATE:
inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN);
zlog_debug ("%s: %s %s/%d: desync: RR is in RIB, but gate differs (ours is %s)",
- __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen, gate_buf);
+ __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen, gate_buf);
break;
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s/%d: done Ok",
- __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
rib_lookup_and_dump (&p);
return;
break;
@@ -843,18 +842,18 @@
{
case ZEBRA_RIB_FOUND_EXACT:
zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, while already not in FIB",
- __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
rib_lookup_and_dump (&p);
break;
case ZEBRA_RIB_FOUND_CONNECTED:
case ZEBRA_RIB_FOUND_NOGATE:
zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, plus gate differs",
- __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
rib_lookup_and_dump (&p);
break;
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s/%d: done Ok",
- __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
rib_lookup_and_dump (&p);
return;
break;
@@ -862,7 +861,7 @@
break;
default:
zlog_debug ("%s: %s/%d: warning: loopback RTM of type %s received",
- __func__, buf, p.prefixlen, LOOKUP (rtm_type_str, rtm->rtm_type));
+ __func__, buf, p.prefixlen, lookup (rtm_type_str, rtm->rtm_type));
}
return;
}
@@ -1063,7 +1062,7 @@
static void
rtmsg_debug (struct rt_msghdr *rtm)
{
- zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, LOOKUP (rtm_type_str, rtm->rtm_type));
+ zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_type));
rtm_flag_dump (rtm->rtm_flags);
zlog_debug ("Kernel: message seq %d", rtm->rtm_seq);
zlog_debug ("Kernel: pid %d, rtm_addrs 0x%x", rtm->rtm_pid, rtm->rtm_addrs);
--- zebra/kernel_socket.h 13 Aug 2007 16:03:07 -0000 1.2
+++ zebra/kernel_socket.h 14 Sep 2007 09:55:16 -0000
@@ -29,6 +29,5 @@
extern int rtm_write (int, union sockunion *, union sockunion *,
union sockunion *, unsigned int, int, int);
extern struct message rtm_type_str[];
-extern int rtm_type_str_max;
#endif /* __ZEBRA_KERNEL_SOCKET_H */
--- zebra/rt_socket.c 12 Sep 2007 15:24:27 -0000 1.14
+++ zebra/rt_socket.c 14 Sep 2007 09:55:16 -0000
@@ -211,14 +211,14 @@
if (!IS_ZEBRA_DEBUG_RIB)
inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s",
- __func__, prefix_buf, p->prefixlen, error, LOOKUP (rtm_type_str, cmd));
+ __func__, prefix_buf, p->prefixlen, error, lookup (rtm_type_str, cmd));
break;
}
} /* if (cmd and flags make sense) */
else
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug ("%s: odd command %s for flags %d",
- __func__, LOOKUP (rtm_type_str, cmd), nexthop->flags);
+ __func__, lookup (rtm_type_str, cmd), nexthop->flags);
} /* for (nexthop = ... */
/* If there was no useful nexthop, then complain. */

View File

@ -0,0 +1,39 @@
--- zebra/main.c 2007-05-02 19:28:33.000000000 +0400
+++ zebra/main.c 2007-09-14 17:34:12.000000000 +0400
@@ -346,11 +346,13 @@
zebra_snmp_init ();
#endif /* HAVE_SNMP */
- /* Clean up self inserted route. */
- if (! keep_kernel_mode)
- rib_sweep_route ();
-
- /* Configuration file read*/
+ /* Process the configuration file. Among other configuration
+ * directives we can meet those installing static routes. Such
+ * requests will not be executed immediately, but queued in
+ * zebra->ribq structure until we enter the main execution loop.
+ * The notifications from kernel will show originating PID equal
+ * to that after daemon() completes (if ever called).
+ */
vty_read_config (config_file, config_default);
/* Don't start execution if we are in dry-run mode */
@@ -374,6 +376,17 @@
/* Output pid of zebra. */
pid_output (pid_file);
+ /* After we have successfully acquired the pidfile, we can be sure
+ * about being the only copy of zebra process, which is submitting
+ * changes to the FIB.
+ * Clean up zebra-originated routes. The requests will be sent to OS
+ * immediately, so originating PID in notifications from kernel
+ * will be equal to the current getpid(). To know about such routes,
+ * we have to have route_read() called before.
+ */
+ if (! keep_kernel_mode)
+ rib_sweep_route ();
+
/* Needed for BSD routing socket. */
pid = getpid ();

View File

@ -1,642 +0,0 @@
--- lib/zebra.h.orig 2007-06-14 14:02:13.000000000 +0400
+++ lib/zebra.h 2007-08-08 12:19:21.000000000 +0400
@@ -454,10 +454,12 @@
#define ZEBRA_FAMILY_MAX 3
/* Error codes of zebra. */
+#define ZEBRA_ERR_NOERROR 0
#define ZEBRA_ERR_RTEXIST -1
#define ZEBRA_ERR_RTUNREACH -2
#define ZEBRA_ERR_EPERM -3
#define ZEBRA_ERR_RTNOEXIST -4
+#define ZEBRA_ERR_KERNEL -5
/* Zebra message flags */
#define ZEBRA_FLAG_INTERNAL 0x01
--- zebra/kernel_socket.c.orig 2007-07-27 20:40:57.000000000 +0400
+++ zebra/kernel_socket.c 2007-08-08 14:52:36.000000000 +0400
@@ -160,6 +160,7 @@
#endif /* RTM_IFANNOUNCE */
{0, NULL}
};
+int rtm_type_str_max = sizeof (rtm_type_str) / sizeof (struct message) - 1;
struct message rtm_flag_str[] =
{
@@ -737,14 +738,12 @@
zebra_flags = 0;
- /* Discard self send message. */
- if (rtm->rtm_type != RTM_GET
- && (rtm->rtm_pid == pid || rtm->rtm_pid == old_pid))
- return;
-
/* Read destination and netmask and gateway from rtm message
structure. */
flags = rtm_read_mesg (rtm, &dest, &mask, &gate, ifname, &ifnlen);
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug ("%s: got rtm of type %d (%s)", __func__, rtm->rtm_type,
+ LOOKUP (rtm_type_str, rtm->rtm_type));
#ifdef RTF_CLONED /*bsdi, netbsd 1.6*/
if (flags & RTF_CLONED)
@@ -786,6 +785,79 @@
else
p.prefixlen = ip_masklen (mask.sin.sin_addr);
+ /* Catch self originated messages and match them against our current RIB.
+ * At the same time, ignore unconfirmed messages, they should be tracked
+ * by rtm_write() and kernel_rtm_ipv4().
+ */
+ if (rtm->rtm_type != RTM_GET
+ && (rtm->rtm_pid == pid || rtm->rtm_pid == old_pid))
+ {
+ char buf[INET_ADDRSTRLEN], gate_buf[INET_ADDRSTRLEN];
+ int ret;
+ if (!(flags & RTF_DONE))
+ return;
+ if (! IS_ZEBRA_DEBUG_RIB)
+ return;
+ ret = rib_lookup_ipv4_route (&p, &gate);
+ inet_ntop (AF_INET, &p.prefix, buf, INET_ADDRSTRLEN);
+ switch (rtm->rtm_type)
+ {
+ case RTM_ADD:
+ case RTM_GET:
+ case RTM_CHANGE:
+ /* The kernel notifies us about a new route in FIB created by us.
+ Do we have a correspondent entry in our RIB? */
+ switch (ret)
+ {
+ case ZEBRA_RIB_NOTFOUND:
+ zlog_debug ("%s: %s %s/%d: desync: RR isn't yet in RIB, while already in FIB",
+ __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ break;
+ case ZEBRA_RIB_FOUND_CONNECTED:
+ case ZEBRA_RIB_FOUND_NOGATE:
+ inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN);
+ zlog_debug ("%s: %s %s/%d: desync: RR is in RIB, but gate differs (ours is %s)",
+ __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen, gate_buf);
+ break;
+ case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
+ zlog_debug ("%s: %s %s/%d: done Ok",
+ __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ rib_lookup_and_dump (&p);
+ return;
+ break;
+ }
+ break;
+ case RTM_DELETE:
+ /* The kernel notifies us about a route deleted by us. Do we still
+ have it in the RIB? Do we have anything instead? */
+ switch (ret)
+ {
+ case ZEBRA_RIB_FOUND_EXACT:
+ zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, while already not in FIB",
+ __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ rib_lookup_and_dump (&p);
+ break;
+ case ZEBRA_RIB_FOUND_CONNECTED:
+ case ZEBRA_RIB_FOUND_NOGATE:
+ zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, plus gate differs",
+ __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ rib_lookup_and_dump (&p);
+ break;
+ case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
+ zlog_debug ("%s: %s %s/%d: done Ok",
+ __func__, LOOKUP (rtm_type_str, rtm->rtm_type), buf, p.prefixlen);
+ rib_lookup_and_dump (&p);
+ return;
+ break;
+ }
+ break;
+ default:
+ zlog_debug ("%s: %s/%d: warning: loopback RTM of type %s received",
+ __func__, buf, p.prefixlen, LOOKUP (rtm_type_str, rtm->rtm_type));
+ }
+ return;
+ }
+
/* Change, delete the old prefix, we have no further information
* to specify the route really
*/
@@ -903,7 +975,13 @@
{
if (!ifp)
{
- zlog_warn ("no gateway found for interface index %d", index);
+ char dest_buf[INET_ADDRSTRLEN] = "NULL", mask_buf[INET_ADDRSTRLEN] = "255.255.255.255";
+ if (dest)
+ inet_ntop (AF_INET, &dest->sin.sin_addr, dest_buf, INET_ADDRSTRLEN);
+ if (mask)
+ inet_ntop (AF_INET, &mask->sin.sin_addr, mask_buf, INET_ADDRSTRLEN);
+ zlog_warn ("%s: %s/%s: gate == NULL and no gateway found for ifindex %d",
+ __func__, dest_buf, mask_buf, index);
return -1;
}
gate = (union sockunion *) & ifp->sdl;
@@ -959,11 +1037,13 @@
return ZEBRA_ERR_RTEXIST;
if (errno == ENETUNREACH)
return ZEBRA_ERR_RTUNREACH;
+ if (errno == ESRCH)
+ return ZEBRA_ERR_RTNOEXIST;
- zlog_warn ("write : %s (%d)", safe_strerror (errno), errno);
- return -1;
+ zlog_warn ("%s: write : %s (%d)", __func__, safe_strerror (errno), errno);
+ return ZEBRA_ERR_KERNEL;
}
- return 0;
+ return ZEBRA_ERR_NOERROR;
}
@@ -974,17 +1054,7 @@
static void
rtmsg_debug (struct rt_msghdr *rtm)
{
- const char *type = "Unknown";
- struct message *mes;
-
- for (mes = rtm_type_str; mes->str; mes++)
- if (mes->key == rtm->rtm_type)
- {
- type = mes->str;
- break;
- }
-
- zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, type);
+ zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, LOOKUP (rtm_type_str, rtm->rtm_type));
rtm_flag_dump (rtm->rtm_flags);
zlog_debug ("Kernel: message seq %d", rtm->rtm_seq);
zlog_debug ("Kernel: pid %d, rtm_addrs 0x%x", rtm->rtm_pid, rtm->rtm_addrs);
--- zebra/kernel_socket.h.orig 2005-11-24 18:10:48.000000000 +0300
+++ zebra/kernel_socket.h 2007-08-08 12:19:21.000000000 +0400
@@ -28,5 +28,7 @@
extern int ifm_read (struct if_msghdr *);
extern int rtm_write (int, union sockunion *, union sockunion *,
union sockunion *, unsigned int, int, int);
+extern struct message rtm_type_str[];
+extern int rtm_type_str_max;
#endif /* __ZEBRA_KERNEL_SOCKET_H */
--- zebra/rib.h.orig 2007-05-02 19:28:33.000000000 +0400
+++ zebra/rib.h 2007-08-08 12:19:21.000000000 +0400
@@ -211,6 +211,15 @@
extern struct nexthop *nexthop_blackhole_add (struct rib *);
extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
struct in_addr *);
+extern void rib_lookup_and_dump (struct prefix_ipv4 *);
+extern void rib_dump (const char *, const struct prefix_ipv4 *, const struct rib *);
+extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *);
+#define ZEBRA_RIB_LOOKUP_ERROR -1
+#define ZEBRA_RIB_FOUND_EXACT 0
+#define ZEBRA_RIB_FOUND_NOGATE 1
+#define ZEBRA_RIB_FOUND_CONNECTED 2
+#define ZEBRA_RIB_NOTFOUND 3
+
#ifdef HAVE_IPV6
extern struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *);
#endif /* HAVE_IPV6 */
--- zebra/rt_socket.c.orig 2007-08-08 12:08:40.000000000 +0400
+++ zebra/rt_socket.c 2007-08-08 12:41:01.000000000 +0400
@@ -32,6 +32,7 @@
#include "zebra/debug.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
+#include "zebra/kernel_socket.h"
extern struct zebra_privs_t zserv_privs;
@@ -75,7 +76,10 @@
unsigned int ifindex = 0;
int gate = 0;
int error;
+ char prefix_buf[INET_ADDRSTRLEN];
+ if (IS_ZEBRA_DEBUG_RIB)
+ inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
memset (&sin_dest, 0, sizeof (struct sockaddr_in));
sin_dest.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
@@ -95,6 +99,7 @@
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
{
gate = 0;
+ char gate_buf[INET_ADDRSTRLEN] = "NULL";
if ((cmd == RTM_ADD
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
@@ -156,29 +161,61 @@
rib->flags,
rib->metric);
-#if 0
- if (error)
- {
- zlog_info ("kernel_rtm_ipv4(): nexthop %d add error=%d.",
- nexthop_num, error);
- }
-#endif
- if (error == 0)
- {
- nexthop_num++;
- if (cmd == RTM_ADD)
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
- }
- }
- }
-
- /* If there is no useful nexthop then return. */
- if (nexthop_num == 0)
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("kernel_rtm_ipv4(): No useful nexthop.");
- return 0;
- }
+ if (IS_ZEBRA_DEBUG_RIB)
+ {
+ if (!gate)
+ {
+ zlog_debug ("%s: %s/%d: attention! gate not found for rib %p",
+ __func__, prefix_buf, p->prefixlen, rib);
+ rib_dump (__func__, (struct prefix_ipv4 *)p, rib);
+ }
+ else
+ inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
+ }
+
+ switch (error)
+ {
+ /* We only flag nexthops as being in FIB if rtm_write() did its work. */
+ case ZEBRA_ERR_NOERROR:
+ nexthop_num++;
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug ("%s: %s/%d: successfully did NH %s",
+ __func__, prefix_buf, p->prefixlen, gate_buf);
+ if (cmd == RTM_ADD)
+ SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+ break;
+
+ /* The only valid case for this error is kernel's failure to install
+ * a multipath route, which is common for FreeBSD. This should be
+ * ignored silently, but logged as an error otherwise.
+ */
+ case ZEBRA_ERR_RTEXIST:
+ if (cmd != RTM_ADD)
+ zlog_err ("%s: rtm_write() returned %d for command %d",
+ __func__, error, cmd);
+ continue;
+ break;
+
+ /* Given that our NEXTHOP_FLAG_FIB matches real kernel FIB, it isn't
+ * normal to get any other messages in ANY case.
+ */
+ case ZEBRA_ERR_RTNOEXIST:
+ case ZEBRA_ERR_RTUNREACH:
+ default:
+ zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s",
+ __func__, prefix_buf, p->prefixlen, error, LOOKUP (rtm_type_str, cmd));
+ break;
+ }
+ } /* if (cmd and flags make sense) */
+ else
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug ("%s: odd command %s for flags %d",
+ __func__, LOOKUP (rtm_type_str, cmd), nexthop->flags);
+ } /* for (nexthop = ... */
+
+ /* If there was no useful nexthop, then complain. */
+ if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, rib);
return 0; /*XXX*/
}
--- zebra/zebra_rib.c.orig 2007-06-25 14:17:53.000000000 +0400
+++ zebra/zebra_rib.c 2007-08-08 12:30:23.000000000 +0400
@@ -631,6 +631,82 @@
return NULL;
}
+/*
+ * This clone function, unlike its original rib_lookup_ipv4(), checks
+ * if specified IPv4 route record (prefix/mask -> gate) exists in
+ * the whole RIB and has ZEBRA_FLAG_SELECTED set.
+ *
+ * Return values:
+ * -1: error
+ * 0: exact match found
+ * 1: a match was found with a different gate
+ * 2: connected route found
+ * 3: no matches found
+ */
+int
+rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct rib *match;
+ struct nexthop *nexthop;
+
+ /* Lookup table. */
+ table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ if (! table)
+ return ZEBRA_RIB_LOOKUP_ERROR;
+
+ /* Scan the RIB table for exactly matching RIB entry. */
+ rn = route_node_lookup (table, (struct prefix *) p);
+
+ /* No route for this prefix. */
+ if (! rn)
+ return ZEBRA_RIB_NOTFOUND;
+
+ /* Unlock node. */
+ route_unlock_node (rn);
+
+ /* Find out if a "selected" RR for the discovered RIB entry exists ever. */
+ for (match = rn->info; match; match = match->next)
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
+
+ /* None such found :( */
+ if (!match)
+ return ZEBRA_RIB_NOTFOUND;
+
+ if (match->type == ZEBRA_ROUTE_CONNECT)
+ return ZEBRA_RIB_FOUND_CONNECTED;
+
+ /* Ok, we have a cood candidate, let's check it's nexthop list... */
+ for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
+ {
+ /* We are happy with either direct or recursive hexthop */
+ if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
+ nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
+ return ZEBRA_RIB_FOUND_EXACT;
+ else
+ {
+ if (IS_ZEBRA_DEBUG_RIB)
+ {
+ char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
+ inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
+ inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
+ inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
+ zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
+ }
+ return ZEBRA_RIB_FOUND_NOGATE;
+ }
+ }
+
+ return ZEBRA_RIB_NOTFOUND;
+}
+
#ifdef HAVE_IPV6
struct rib *
rib_match_ipv6 (struct in6_addr *addr)
@@ -694,6 +770,16 @@
#define RIB_SYSTEM_ROUTE(R) \
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
+/* This function verifies reachability of one given nexthop, which can be
+ * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
+ * in nexthop->flags field. If the 4th parameter, 'set', is non-zero,
+ * nexthop->ifindex will be updated appropriately as well.
+ * An existing route map can turn (otherwise active) nexthop into inactive, but
+ * not vice versa.
+ *
+ * The return value is the final value of 'ACTIVE' flag.
+ */
+
static int
nexthop_active_check (struct route_node *rn, struct rib *rib,
struct nexthop *nexthop, int set)
@@ -839,6 +925,7 @@
#endif /* HAVE_IPV6 */
}
+ /* This condition is never met, if we are using rt_socket.c */
if (ret < 0)
{
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
@@ -860,6 +947,8 @@
break;
#ifdef HAVE_IPV6
case AF_INET6:
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug ("%s: calling kernel_delete_ipv4 (%p, %p)", __func__, rn, rib);
ret = kernel_delete_ipv6 (&rn->p, rib);
break;
#endif /* HAVE_IPV6 */
@@ -903,6 +992,9 @@
for (rib = rn->info; rib; rib = next)
{
+ /* The next pointer is saved, because current pointer
+ * may be passed to rib_unlink() in the middle of iteration.
+ */
next = rib->next;
/* Currently installed rib. */
@@ -978,9 +1070,16 @@
/* metric tie-breaks equal distance */
if (rib->metric <= select->metric)
select = rib;
- }
-
- /* Same route is selected. */
+ } /* for (rib = rn->info; rib; rib = next) */
+
+ /* After the cycle is finished, the following pointers will be set:
+ * select --- the winner RIB entry, if any was found, otherwise NULL
+ * fib --- the SELECTED RIB entry, if any, otherwise NULL
+ * del --- equal to fib, if fib is queued for deletion, NULL otherwise
+ * rib --- NULL
+ */
+
+ /* Same RIB entry is selected. Update FIB and finish. */
if (select && select == fib)
{
if (IS_ZEBRA_DEBUG_RIB)
@@ -1019,7 +1118,10 @@
goto end;
}
- /* Uninstall old rib from forwarding table. */
+ /* At this point we either haven't found the best RIB entry or it is
+ * different from what we currently intend to flag with SELECTED. In both
+ * cases, if a RIB block is present in FIB, it should be withdrawn.
+ */
if (fib)
{
if (IS_ZEBRA_DEBUG_RIB)
@@ -1033,7 +1135,10 @@
nexthop_active_update (rn, fib, 1);
}
- /* Install new rib into forwarding table. */
+ /* Regardless of some RIB entry being SELECTED or not before, now we can
+ * tell, that if a new winner exists, FIB is still not updated with this
+ * data, but ready to be.
+ */
if (select)
{
if (IS_ZEBRA_DEBUG_RIB)
@@ -1350,16 +1455,127 @@
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
/* Link new rib to node.*/
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug ("%s: calling rib_addnode (%p, %p)", __func__, rn, rib);
rib_addnode (rn, rib);
/* Free implicit route.*/
if (same)
+ {
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug ("%s: calling rib_delnode (%p, %p)", __func__, rn, rib);
rib_delnode (rn, same);
+ }
route_unlock_node (rn);
return 0;
}
+/* This function dumps the contents of a given RIB entry into
+ * standard debug log. Calling function name and IP prefix in
+ * question are passed as 1st and 2nd arguments.
+ */
+
+void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib * rib)
+{
+ char straddr1[INET_ADDRSTRLEN], straddr2[INET_ADDRSTRLEN];
+ struct nexthop *nexthop;
+
+ inet_ntop (AF_INET, &p->prefix, straddr1, INET_ADDRSTRLEN);
+ zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
+ zlog_debug
+ (
+ "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
+ func,
+ rib->refcnt,
+ rib->uptime,
+ rib->type,
+ rib->table
+ );
+ zlog_debug
+ (
+ "%s: metric == %u, distance == %u, flags == %u, status == %u",
+ func,
+ rib->metric,
+ rib->distance,
+ rib->flags,
+ rib->status
+ );
+ zlog_debug
+ (
+ "%s: nexthop_num == %u, nexthop_active_num == %u, nexthop_fib_num == %u",
+ func,
+ rib->nexthop_num,
+ rib->nexthop_active_num,
+ rib->nexthop_fib_num
+ );
+ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ {
+ inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, straddr1, INET_ADDRSTRLEN);
+ inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, straddr2, INET_ADDRSTRLEN);
+ zlog_debug
+ (
+ "%s: NH %s (%s) with flags %s%s%s",
+ func,
+ straddr1,
+ straddr2,
+ (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
+ (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
+ (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "")
+ );
+ }
+ zlog_debug ("%s: dump complete", func);
+}
+
+/* This is an exported helper to rtm_read() to dump the strange
+ * RIB entry found by rib_lookup_ipv4_route()
+ */
+
+void rib_lookup_and_dump (struct prefix_ipv4 * p)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct rib *rib;
+ char prefix_buf[INET_ADDRSTRLEN];
+
+ /* Lookup table. */
+ table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ if (! table)
+ {
+ zlog_err ("%s: vrf_table() returned NULL", __func__);
+ return;
+ }
+
+ inet_ntop (AF_INET, &p->prefix.s_addr, prefix_buf, INET_ADDRSTRLEN);
+ /* Scan the RIB table for exactly matching RIB entry. */
+ rn = route_node_lookup (table, (struct prefix *) p);
+
+ /* No route for this prefix. */
+ if (! rn)
+ {
+ zlog_debug ("%s: lookup failed for %s/%d", __func__, prefix_buf, p->prefixlen);
+ return;
+ }
+
+ /* Unlock node. */
+ route_unlock_node (rn);
+
+ /* let's go */
+ for (rib = rn->info; rib; rib = rib->next)
+ {
+ zlog_debug
+ (
+ "%s: rn %p, rib %p: %s, %s",
+ __func__,
+ rn,
+ rib,
+ (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
+ (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
+ );
+ rib_dump (__func__, p, rib);
+ }
+}
+
int
rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
{
@@ -1408,10 +1624,24 @@
/* Link new rib to node.*/
rib_addnode (rn, rib);
+ if (IS_ZEBRA_DEBUG_RIB)
+ {
+ zlog_debug ("%s: called rib_addnode (%p, %p) on new RIB entry",
+ __func__, rn, rib);
+ rib_dump (__func__, p, rib);
+ }
/* Free implicit route.*/
if (same)
+ {
+ if (IS_ZEBRA_DEBUG_RIB)
+ {
+ zlog_debug ("%s: calling rib_delnode (%p, %p) on existing RIB entry",
+ __func__, rn, same);
+ rib_dump (__func__, p, same);
+ }
rib_delnode (rn, same);
+ }
route_unlock_node (rn);
return 0;

View File

@ -1,47 +0,0 @@
--- zebra/zebra_rib.c.orig 2007-06-25 14:17:53.000000000 +0400
+++ zebra/zebra_rib.c 2007-08-08 11:38:18.000000000 +0400
@@ -795,27 +795,32 @@
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
+/* Iterate over all nexthops of the given RIB entry and refresh their
+ * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any
+ * nexthop is found to toggle the ACTIVE flag, the whole rib structure
+ * is flagged with ZEBRA_FLAG_CHANGED. The 4th 'set' argument is
+ * transparently passed to nexthop_active_check().
+ *
+ * Return value is the new number of active nexthops.
+ */
+
static int
nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
{
struct nexthop *nexthop;
- int active;
+ int prev_active, new_active;
rib->nexthop_active_num = 0;
UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
- {
- active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
-
- nexthop_active_check (rn, rib, nexthop, set);
- if ((MULTIPATH_NUM == 0 || rib->nexthop_active_num < MULTIPATH_NUM)
- && active != CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
-
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- rib->nexthop_active_num++;
- }
+ {
+ prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
+ rib->nexthop_active_num++;
+ if (prev_active != new_active)
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+ }
return rib->nexthop_active_num;
}

View File

@ -0,0 +1,81 @@
Index: zebra/kernel_socket.c
===================================================================
RCS file: /var/cvsroot/quagga/zebra/kernel_socket.c,v
retrieving revision 1.48
diff -u -r1.48 kernel_socket.c
--- zebra/kernel_socket.c 14 Sep 2007 11:31:55 -0000 1.48
+++ zebra/kernel_socket.c 14 Sep 2007 14:11:28 -0000
@@ -799,8 +799,7 @@
* At the same time, ignore unconfirmed messages, they should be tracked
* by rtm_write() and kernel_rtm_ipv4().
*/
- if (rtm->rtm_type != RTM_GET
- && (rtm->rtm_pid == pid || rtm->rtm_pid == old_pid))
+ if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
{
char buf[INET_ADDRSTRLEN], gate_buf[INET_ADDRSTRLEN];
int ret;
Index: zebra/main.c
===================================================================
RCS file: /var/cvsroot/quagga/zebra/main.c,v
retrieving revision 1.27
diff -u -r1.27 main.c
--- zebra/main.c 14 Sep 2007 13:31:52 -0000 1.27
+++ zebra/main.c 14 Sep 2007 14:11:28 -0000
@@ -47,7 +47,6 @@
};
/* process id. */
-pid_t old_pid;
pid_t pid;
/* Pacify zclient.o in libzebra, which expects this variable. */
@@ -366,9 +365,6 @@
if (batch_mode)
exit (0);
- /* Needed for BSD routing socket. */
- old_pid = getpid ();
-
/* Daemonize. */
if (daemon_mode)
daemon (0, 0);
Index: zebra/test_main.c
===================================================================
RCS file: /var/cvsroot/quagga/zebra/test_main.c,v
retrieving revision 1.1
diff -u -r1.1 test_main.c
--- zebra/test_main.c 27 Jul 2006 19:59:58 -0000 1.1
+++ zebra/test_main.c 14 Sep 2007 14:11:28 -0000
@@ -43,7 +43,6 @@
};
/* process id. */
-pid_t old_pid;
pid_t pid;
/* zebra_rib's workqueue hold time. Private export for use by test code only */
@@ -313,9 +312,6 @@
if (batch_mode)
exit (0);
- /* Needed for BSD routing socket. */
- old_pid = getpid ();
-
/* Daemonize. */
if (daemon_mode)
daemon (0, 0);
Index: zebra/zserv.h
===================================================================
RCS file: /var/cvsroot/quagga/zebra/zserv.h,v
retrieving revision 1.15
diff -u -r1.15 zserv.h
--- zebra/zserv.h 2 May 2007 16:05:35 -0000 1.15
+++ zebra/zserv.h 14 Sep 2007 14:11:28 -0000
@@ -107,6 +107,5 @@
extern int zsend_router_id_update(struct zserv *, struct prefix *);
extern pid_t pid;
-extern pid_t old_pid;
#endif /* _ZEBRA_ZEBRA_H */

View File

@ -1,294 +0,0 @@
--- lib/sockopt.c.orig 2007-07-09 16:36:45.000000000 +0400
+++ lib/sockopt.c 2007-08-02 17:38:50.000000000 +0400
@@ -29,20 +29,49 @@
int ret;
if ( (ret = setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *)
&size, sizeof (int))) < 0)
zlog_err ("fd %d: can't setsockopt SO_RCVBUF to %d: %s",
sock,size,safe_strerror(errno));
return ret;
}
+int
+setsockopt_so_sendbuf (const int sock, int size)
+{
+ int ret = setsockopt (sock, SOL_SOCKET, SO_SNDBUF,
+ (char *)&size, sizeof (int));
+
+ if (ret < 0)
+ zlog_err ("fd %d: can't setsockopt SO_SNDBUF to %d: %s",
+ sock, size, safe_strerror (errno));
+
+ return ret;
+}
+
+int
+getsockopt_so_sendbuf (const int sock)
+{
+ u_int32_t optval;
+ socklen_t optlen = sizeof (optval);
+ int ret = getsockopt (sock, SOL_SOCKET, SO_SNDBUF,
+ (char *)&optval, &optlen);
+ if (ret < 0)
+ {
+ zlog_err ("fd %d: can't getsockopt SO_SNDBUF: %d (%s)",
+ sock, errno, safe_strerror (errno));
+ return ret;
+ }
+ return optval;
+}
+
static void *
getsockopt_cmsg_data (struct msghdr *msgh, int level, int type)
{
struct cmsghdr *cmsg;
void *ptr = NULL;
for (cmsg = ZCMSG_FIRSTHDR(msgh);
cmsg != NULL;
cmsg = CMSG_NXTHDR(msgh, cmsg))
if (cmsg->cmsg_level == level && cmsg->cmsg_type)
--- lib/sockopt.h.orig 2007-07-09 16:36:45.000000000 +0400
+++ lib/sockopt.h 2007-08-01 17:37:33.000000000 +0400
@@ -16,20 +16,22 @@
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _ZEBRA_SOCKOPT_H
#define _ZEBRA_SOCKOPT_H
extern int setsockopt_so_recvbuf (int sock, int size);
+extern int setsockopt_so_sendbuf (const int sock, int size);
+extern int getsockopt_so_sendbuf (const int sock);
#ifdef HAVE_IPV6
extern int setsockopt_ipv6_pktinfo (int, int);
extern int setsockopt_ipv6_checksum (int, int);
extern int setsockopt_ipv6_multicast_hops (int, int);
extern int setsockopt_ipv6_unicast_hops (int, int);
extern int setsockopt_ipv6_hoplimit (int, int);
extern int setsockopt_ipv6_multicast_loop (int, int);
#endif /* HAVE_IPV6 */
--- ospfd/ospfd.c.orig 2007-05-01 03:42:20.000000000 +0400
+++ ospfd/ospfd.c 2007-08-01 19:07:46.000000000 +0400
@@ -205,20 +205,22 @@
new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
new, new->lsa_refresh_interval);
new->lsa_refresher_started = quagga_time (NULL);
if ((new->fd = ospf_sock_init()) < 0)
{
zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
"a socket");
exit(1);
}
+ new->maxsndbuflen = 0;
+ ospf_adjust_sndbuflen (new, OSPF_SNDBUFLEN_DEFAULT);
if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
{
zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
OSPF_MAX_PACKET_SIZE+1);
exit(1);
}
new->t_read = thread_add_read (master, ospf_read, new, new->fd);
new->oi_write_q = list_new ();
return new;
--- ospfd/ospfd.h.orig 2006-10-18 00:45:04.000000000 +0400
+++ ospfd/ospfd.h 2007-08-01 17:10:36.000000000 +0400
@@ -122,20 +122,23 @@
/* OSPF Database Description flags. */
#define OSPF_DD_FLAG_MS 0x01
#define OSPF_DD_FLAG_M 0x02
#define OSPF_DD_FLAG_I 0x04
#define OSPF_DD_FLAG_ALL 0x07
#define OSPF_LS_REFRESH_SHIFT (60 * 15)
#define OSPF_LS_REFRESH_JITTER 60
+/* Initial send buffer size for ospfd raw sending socket. */
+#define OSPF_SNDBUFLEN_DEFAULT 1024
+
/* OSPF master for system wide configuration and variables. */
struct ospf_master
{
/* OSPF instance. */
struct list *ospf;
/* OSPF thread master. */
struct thread_master *master;
/* Zebra interface list. */
@@ -259,20 +262,21 @@
#ifdef HAVE_OPAQUE_LSA
struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
#endif /* HAVE_OPAQUE_LSA */
struct thread *t_maxage; /* MaxAge LSA remover timer. */
struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */
struct thread *t_deferred_shutdown; /* deferred/stub-router shutdown timer*/
struct thread *t_write;
struct thread *t_read;
int fd;
+ int maxsndbuflen;
struct stream *ibuf;
struct list *oi_write_q;
/* Distribute lists out of other route sources. */
struct
{
char *name;
struct access_list *list;
} dlist[ZEBRA_ROUTE_MAX];
#define DISTRIBUTE_NAME(O,T) (O)->dlist[T].name
--- ospfd/ospf_interface.c.orig 2007-04-22 17:26:38.000000000 +0400
+++ ospfd/ospf_interface.c 2007-08-02 18:31:53.000000000 +0400
@@ -774,20 +774,25 @@
int
ospf_if_up (struct ospf_interface *oi)
{
if (oi == NULL)
return 0;
if (oi->type == OSPF_IFTYPE_LOOPBACK)
OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
else
{
+ struct ospf *ospf = ospf_lookup ();
+ if (ospf != NULL)
+ ospf_adjust_sndbuflen (ospf, oi->ifp->mtu);
+ else
+ zlog_warn ("%s: ospf_lookup() returned NULL");
ospf_if_stream_set (oi);
OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
}
return 1;
}
int
ospf_if_down (struct ospf_interface *oi)
{
--- ospfd/ospf_network.c.orig 2005-05-09 22:37:56.000000000 +0400
+++ ospfd/ospf_network.c 2007-08-01 20:03:26.000000000 +0400
@@ -34,20 +34,21 @@
extern struct zebra_privs_t ospfd_privs;
#include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_packet.h"
+#include "ospfd/ospf_dump.h"
/* Join to the OSPF ALL SPF ROUTERS multicast group. */
int
ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
unsigned int ifindex)
{
int ret;
@@ -226,10 +227,44 @@
zlog_warn ("Can't set pktinfo option for fd %d", ospf_sock);
if (ospfd_privs.change (ZPRIVS_LOWER))
{
zlog_err ("ospf_sock_init: could not lower privs, %s",
safe_strerror (errno) );
}
return ospf_sock;
}
+
+void
+ospf_adjust_sndbuflen (struct ospf * ospf, int buflen)
+{
+ int ret, newbuflen;
+ /* Check if any work has to be done at all. */
+ if (ospf->maxsndbuflen >= buflen)
+ return;
+ if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("%s: adjusting OSPF send buffer size to %d",
+ __func__, buflen);
+ if (ospfd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("%s: could not raise privs, %s", __func__,
+ safe_strerror (errno));
+ /* Now we try to set SO_SNDBUF to what our caller has requested
+ * (OSPF_SNDBUFLEN_DEFAULT initially, which seems to be a sane
+ * default; or the MTU of a newly added interface). However,
+ * if the OS has truncated the actual buffer size to somewhat
+ * less or bigger size, try to detect it and update our records
+ * appropriately.
+ */
+ ret = setsockopt_so_sendbuf (ospf->fd, buflen);
+ newbuflen = getsockopt_so_sendbuf (ospf->fd);
+ if (ret < 0 || newbuflen != buflen)
+ zlog_warn ("%s: tried to set SO_SNDBUF to %d, but got %d",
+ __func__, buflen, newbuflen);
+ if (newbuflen >= 0)
+ ospf->maxsndbuflen = newbuflen;
+ else
+ zlog_warn ("%s: failed to get SO_SNDBUF", __func__);
+ if (ospfd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("%s: could not lower privs, %s", __func__,
+ safe_strerror (errno));
+}
--- ospfd/ospf_network.h.orig 2005-05-06 21:26:18.000000000 +0400
+++ ospfd/ospf_network.h 2007-08-01 19:17:11.000000000 +0400
@@ -27,12 +27,13 @@
extern int ospf_if_add_allspfrouters (struct ospf *, struct prefix *,
unsigned int);
extern int ospf_if_drop_allspfrouters (struct ospf *, struct prefix *,
unsigned int);
extern int ospf_if_add_alldrouters (struct ospf *, struct prefix *,
unsigned int);
extern int ospf_if_drop_alldrouters (struct ospf *, struct prefix *,
unsigned int);
extern int ospf_if_ipmulticast (struct ospf *, struct prefix *, unsigned int);
extern int ospf_sock_init (void);
+extern void ospf_adjust_sndbuflen (struct ospf *, int);
#endif /* _ZEBRA_OSPF_NETWORK_H */
--- ospfd/ospf_packet.c.orig 2007-05-10 00:59:34.000000000 +0400
+++ ospfd/ospf_packet.c 2007-08-01 18:32:36.000000000 +0400
@@ -595,22 +595,26 @@
assert (node);
oi = listgetdata (node);
assert (oi);
#ifdef WANT_OSPF_WRITE_FRAGMENT
/* seed ipid static with low order bits of time */
if (ipid == 0)
ipid = (time(NULL) & 0xffff);
#endif /* WANT_OSPF_WRITE_FRAGMENT */
- /* convenience - max OSPF data per packet */
- maxdatasize = oi->ifp->mtu - sizeof (struct ip);
+ /* convenience - max OSPF data per packet,
+ * and reliability - not more data, than our
+ * socket can accept
+ */
+ maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
+ sizeof (struct ip);
/* Get one packet from queue. */
op = ospf_fifo_head (oi->obuf);
assert (op);
assert (op->length >= OSPF_HEADER_SIZE);
if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
|| op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);

View File

@ -0,0 +1,20 @@
--- ospfd/ospfd.c 21 Aug 2007 16:32:57 -0000 1.51
+++ ospfd/ospfd.c 17 Sep 2007 16:45:40 -0000
@@ -33,6 +33,7 @@
#include "sockunion.h" /* for inet_aton () */
#include "zclient.h"
#include "plist.h"
+#include "sockopt.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h"
@@ -212,8 +213,7 @@
"a socket");
exit(1);
}
- new->maxsndbuflen = 0;
- ospf_adjust_sndbuflen (new, OSPF_SNDBUFLEN_DEFAULT);
+ new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
{
zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",

View File

@ -1,20 +0,0 @@
--- zebra/kernel_socket.c.orig 13 Aug 2007 16:03:07 -0000 1.45
+++ zebra/kernel_socket.c 17 Aug 2007 12:38:10 -0000
@@ -741,6 +741,8 @@
/* Read destination and netmask and gateway from rtm message
structure. */
flags = rtm_read_mesg (rtm, &dest, &mask, &gate, ifname, &ifnlen);
+ if (!(flags & RTF_DONE))
+ return;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: got rtm of type %d (%s)", __func__, rtm->rtm_type,
LOOKUP (rtm_type_str, rtm->rtm_type));
@@ -794,8 +796,6 @@
{
char buf[INET_ADDRSTRLEN], gate_buf[INET_ADDRSTRLEN];
int ret;
- if (!(flags & RTF_DONE))
- return;
if (! IS_ZEBRA_DEBUG_RIB)
return;
ret = rib_lookup_ipv4_route (&p, &gate);

View File

@ -1,18 +0,0 @@
--- zebra/kernel_socket.c.orig 17 Aug 2007 14:16:30 -0000 1.46
+++ zebra/kernel_socket.c 21 Aug 2007 14:30:40 -0000
@@ -472,6 +472,15 @@
if_delete_update (ifp);
}
#endif /* RTM_IFANNOUNCE */
+ if (if_is_up (ifp))
+ {
+#if defined(__bsdi__)
+ if_kvm_get_mtu (ifp);
+#else
+ if_get_mtu (ifp);
+#endif /* __bsdi__ */
+ if_get_metric (ifp);
+ }
}
#ifdef HAVE_NET_RT_IFLIST

View File

@ -1,25 +0,0 @@
diff -Nur zebra/ChangeLog quagga/zebra/ChangeLog
--- zebra/ChangeLog 2007-08-21 20:15:32.000000000 +0400
+++ zebra/ChangeLog 2007-09-06 18:23:30.000000000 +0400
@@ -1,3 +1,9 @@
+2007-09-06 Denis Ovsienko
+
+ * rtread_sysctl.c: (route_read) Set RTF_DONE on the routing
+ messages when fetching initial kernel FIB, so rtm_read()
+ doesn't skip them.
+
2007-08-21 Denis Ovsienko
* ioctl_solaris.c: (if_get_mtu) Don't break things if either
diff -Nur zebra/rtread_sysctl.c zebra/rtread_sysctl.c
--- zebra/rtread_sysctl.c 2005-11-24 18:15:17.000000000 +0300
+++ zebra/rtread_sysctl.c 2007-09-06 18:12:14.000000000 +0400
@@ -68,6 +68,8 @@
for (end = buf + bufsiz; buf < end; buf += rtm->rtm_msglen)
{
rtm = (struct rt_msghdr *) buf;
+ /* We must set RTF_DONE here, so rtm_read() doesn't ignore the message. */
+ SET_FLAG (rtm->rtm_flags, RTF_DONE);
rtm_read (rtm);
}

View File

@ -79,9 +79,6 @@ for daemon in ${quagga_daemons}; do
if [ ${quagga_cmd} = "stop" -a -z $(check_process ${command}) ]; then
continue
fi
if [ ${quagga_cmd} = "restart" -a -z $(check_process ${command}) ]; then
continue
fi
eval flags=\$\{${daemon}_flags:-\"${quagga_flags}\"\}
run_rc_command "$1"
_rc_restart_done=false