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:
parent
4b0a02d453
commit
b7d737ee9d
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=200029
@ -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:
|
||||
|
@ -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
|
||||
|
198
net/quagga/files/patch-cvs-0-bgp-ipv6
Normal file
198
net/quagga/files/patch-cvs-0-bgp-ipv6
Normal 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) ? "[31mfailed![0m" : "[32mOK[0m");
|
||||
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;
|
||||
|
@ -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);
|
12
net/quagga/files/patch-cvs-1-prefix_buf
Normal file
12
net/quagga/files/patch-cvs-1-prefix_buf
Normal 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;
|
@ -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. */
|
108
net/quagga/files/patch-cvs-2-rtm_type_str
Normal file
108
net/quagga/files/patch-cvs-2-rtm_type_str
Normal 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. */
|
39
net/quagga/files/patch-cvs-3-rib_sweep_route
Normal file
39
net/quagga/files/patch-cvs-3-rib_sweep_route
Normal 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 ();
|
||||
|
@ -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;
|
@ -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;
|
||||
}
|
||||
|
81
net/quagga/files/patch-cvs-4-old_pid
Normal file
81
net/quagga/files/patch-cvs-4-old_pid
Normal 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 */
|
@ -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);
|
||||
|
20
net/quagga/files/patch-cvs-5-sndbuf
Normal file
20
net/quagga/files/patch-cvs-5-sndbuf
Normal 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",
|
@ -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);
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user