summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am2
-rw-r--r--babeld/babel_zebra.c2
-rw-r--r--bgpd/Makefile.am8
-rw-r--r--bgpd/bgp_advertise.c41
-rw-r--r--bgpd/bgp_aspath.c80
-rw-r--r--bgpd/bgp_aspath.h1
-rw-r--r--bgpd/bgp_attr.c26
-rw-r--r--bgpd/bgp_attr.h1
-rw-r--r--bgpd/bgp_clist.c2
-rw-r--r--bgpd/bgp_community.c66
-rw-r--r--bgpd/bgp_community.h2
-rw-r--r--bgpd/bgp_debug.c3
-rw-r--r--bgpd/bgp_fsm.c120
-rw-r--r--bgpd/bgp_open.c216
-rw-r--r--bgpd/bgp_packet.c187
-rw-r--r--bgpd/bgp_route.c391
-rw-r--r--bgpd/bgp_route.h8
-rw-r--r--bgpd/bgp_routemap.c147
-rw-r--r--bgpd/bgp_vty.c739
-rw-r--r--bgpd/bgp_zebra.c10
-rw-r--r--bgpd/bgpd.c427
-rw-r--r--bgpd/rfapi/vnc_zebra.c2
-rwxr-xr-xconfigure.ac9
-rw-r--r--debian/control48
-rw-r--r--debian/frr-doc.install1
-rw-r--r--debian/frr.config4
-rw-r--r--debian/patches/50_vtysh__vtysh.conf.sample.diff16
-rw-r--r--debian/patches/75_vtysh__vtysh.c__PAGER.diff26
-rw-r--r--debian/patches/80_vtysh__vtysh.c__privs.diff59
-rw-r--r--debian/patches/82_vtysh__vtysh_user.c__pam.diff10
-rw-r--r--debian/patches/90_configure_ncurses.diff47
-rw-r--r--debian/patches/series5
-rw-r--r--debian/po/POTFILES.in1
-rw-r--r--debian/po/cs.po41
-rw-r--r--debian/po/da.po33
-rw-r--r--debian/po/de.po34
-rw-r--r--debian/po/es.po57
-rw-r--r--debian/po/fr.po42
-rw-r--r--debian/po/it.po35
-rw-r--r--debian/po/ja.po32
-rw-r--r--debian/po/nl.po35
-rw-r--r--debian/po/pt.po34
-rw-r--r--debian/po/pt_BR.po34
-rw-r--r--debian/po/ru.po37
-rw-r--r--debian/po/sv.po40
-rw-r--r--debian/po/templates.pot31
-rwxr-xr-xdebian/rules102
-rw-r--r--debian/watch8
-rw-r--r--debianpkg/Makefile.am38
-rw-r--r--debianpkg/README.Debian (renamed from debian/README.Debian)0
-rw-r--r--debianpkg/README.Maintainer (renamed from debian/README.Maintainer)0
-rw-r--r--debianpkg/README.deb_build.md102
-rw-r--r--debianpkg/backports/.gitignore2
-rw-r--r--debianpkg/backports/README28
-rw-r--r--debianpkg/backports/debian8/debian/source/format1
-rw-r--r--debianpkg/backports/debian8/exclude0
-rw-r--r--debianpkg/backports/debian8/versionext1
-rw-r--r--debianpkg/backports/debian9/debian/source/format1
-rw-r--r--debianpkg/backports/debian9/exclude0
-rw-r--r--debianpkg/backports/debian9/versionext1
-rwxr-xr-xdebianpkg/backports/rules137
-rw-r--r--debianpkg/backports/ubuntu12.04/debian/control56
l---------debianpkg/backports/ubuntu12.04/debian/frr.install1
l---------debianpkg/backports/ubuntu12.04/debian/frr.postinst1
l---------debianpkg/backports/ubuntu12.04/debian/frr.postrm1
-rwxr-xr-xdebianpkg/backports/ubuntu12.04/debian/rules179
-rw-r--r--debianpkg/backports/ubuntu12.04/debian/source/format1
-rw-r--r--debianpkg/backports/ubuntu12.04/exclude0
-rw-r--r--debianpkg/backports/ubuntu12.04/versionext1
-rw-r--r--debianpkg/backports/ubuntu14.04/debian/control56
-rw-r--r--debianpkg/backports/ubuntu14.04/debian/frr.install21
-rw-r--r--debianpkg/backports/ubuntu14.04/debian/frr.postinst (renamed from debian/frr.postinst)4
-rw-r--r--debianpkg/backports/ubuntu14.04/debian/frr.postrm14
-rwxr-xr-xdebianpkg/backports/ubuntu14.04/debian/rules185
-rw-r--r--debianpkg/backports/ubuntu14.04/debian/source/format1
-rw-r--r--debianpkg/backports/ubuntu14.04/exclude0
-rw-r--r--debianpkg/backports/ubuntu14.04/versionext1
-rw-r--r--debianpkg/backports/ubuntu16.04/debian/source/format1
-rw-r--r--debianpkg/backports/ubuntu16.04/exclude0
-rw-r--r--debianpkg/backports/ubuntu16.04/versionext1
-rw-r--r--debianpkg/changelog.in (renamed from debian/changelog)19
-rw-r--r--debianpkg/compat (renamed from debian/compat)0
-rw-r--r--debianpkg/control54
-rw-r--r--debianpkg/copyright (renamed from debian/copyright)0
-rw-r--r--debianpkg/frr-doc.docs (renamed from debian/frr-doc.docs)0
-rw-r--r--debianpkg/frr-doc.info (renamed from debian/frr-doc.info)0
-rw-r--r--debianpkg/frr-doc.install2
-rw-r--r--debianpkg/frr-doc.lintian-overrides (renamed from debian/frr-doc.lintian-overrides)0
-rw-r--r--debianpkg/frr-pythontools.install1
-rw-r--r--debianpkg/frr.conf (renamed from debian/frr.conf)0
-rw-r--r--debianpkg/frr.dirs (renamed from debian/frr.dirs)0
-rw-r--r--debianpkg/frr.docs (renamed from debian/frr.docs)0
-rw-r--r--debianpkg/frr.install (renamed from debian/frr.install)1
-rw-r--r--debianpkg/frr.lintian-overrides (renamed from debian/frr.lintian-overrides)3
-rw-r--r--debianpkg/frr.logrotate (renamed from debian/frr.logrotate)0
-rw-r--r--debianpkg/frr.manpages (renamed from debian/frr.manpages)0
-rw-r--r--debianpkg/frr.pam (renamed from debian/frr.pam)0
-rw-r--r--debianpkg/frr.postinst36
-rw-r--r--debianpkg/frr.postrm (renamed from debian/frr.postrm)0
-rw-r--r--debianpkg/frr.preinst (renamed from debian/frr.preinst)0
-rw-r--r--debianpkg/frr.prerm (renamed from debian/frr.prerm)2
-rwxr-xr-xdebianpkg/rules218
-rw-r--r--debianpkg/source/format (renamed from debian/source/format)0
-rw-r--r--debianpkg/tests/control (renamed from debian/tests/control)0
-rw-r--r--debianpkg/tests/daemons (renamed from debian/tests/daemons)0
-rw-r--r--debianpkg/watchfrr.rc (renamed from debian/watchfrr.rc)0
-rw-r--r--doc/Building_FRR_on_Debian9.md121
-rw-r--r--doc/install.texi4
-rw-r--r--eigrpd/eigrp_zebra.c17
-rw-r--r--isisd/isis_zebra.c2
-rw-r--r--ldpd/lde.c2
-rw-r--r--ldpd/ldp_vty_cmds.c2
-rw-r--r--ldpd/ldp_zebra.c2
-rw-r--r--lib/log.c5
-rw-r--r--lib/route_types.txt2
-rw-r--r--lib/zclient.c35
-rw-r--r--lib/zclient.h31
-rw-r--r--nhrpd/nhrp_route.c2
-rw-r--r--ospf6d/ospf6_zebra.c2
-rw-r--r--ospfd/ospf_asbr.c29
-rw-r--r--ospfd/ospf_asbr.h9
-rw-r--r--ospfd/ospf_flood.c9
-rw-r--r--ospfd/ospf_lsa.c54
-rw-r--r--ospfd/ospf_packet.c63
-rw-r--r--ospfd/ospf_packet.h2
-rw-r--r--ospfd/ospf_vty.c8
-rw-r--r--ospfd/ospf_zebra.c50
-rw-r--r--ospfd/ospf_zebra.h7
-rw-r--r--ospfd/ospfd.c54
-rw-r--r--ospfd/ospfd.h13
-rw-r--r--pimd/pim_zebra.c2
-rw-r--r--pimd/pim_zlookup.c2
-rw-r--r--redhat/daemons2
-rw-r--r--ripd/rip_interface.c20
-rw-r--r--ripd/rip_routemap.c8
-rw-r--r--ripd/rip_zebra.c27
-rw-r--r--ripd/ripd.c83
-rw-r--r--ripd/ripd.h14
-rw-r--r--ripngd/ripng_zebra.c2
-rw-r--r--sharpd/sharp_main.c162
-rw-r--r--sharpd/sharp_vty.c114
-rw-r--r--sharpd/sharp_vty.h26
-rw-r--r--sharpd/sharp_zebra.c208
-rw-r--r--sharpd/sharp_zebra.h29
-rw-r--r--sharpd/sharpd.conf.sample3
-rw-r--r--sharpd/subdir.am21
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/bgpd/test_mpath.c2
-rw-r--r--tests/bgpd/test_packet.c85
-rw-r--r--tests/test_lblmgr.c2
-rw-r--r--tools/etc/frr/daemons1
-rw-r--r--tools/etc/frr/daemons.conf1
-rw-r--r--tools/etc/iproute2/rt_protos.d/frr.conf1
-rwxr-xr-xtools/frr2
-rw-r--r--tools/frr.service4
-rw-r--r--vtysh/Makefile.am4
-rwxr-xr-xvtysh/extract.pl.in2
-rw-r--r--vtysh/vtysh.c9
-rw-r--r--vtysh/vtysh.h4
-rw-r--r--zebra/client_main.c2
-rw-r--r--zebra/label_manager.c2
-rw-r--r--zebra/main.c21
-rw-r--r--zebra/rt_netlink.c23
-rw-r--r--zebra/rt_netlink.h1
-rw-r--r--zebra/zebra_rib.c28
-rw-r--r--zebra/zebra_rnh.c155
-rw-r--r--zebra/zebra_vty.c4
-rw-r--r--zebra/zebra_vxlan.c6
-rw-r--r--zebra/zserv.c93
-rw-r--r--zebra/zserv.h12
171 files changed, 3823 insertions, 2370 deletions
diff --git a/.gitignore b/.gitignore
index 7ed1255d9e..f7c731b4bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@ aclocal.m4
Makefile.in
*.tar.gz
*.tar.gz.asc
+*.tar.?z
.nfs*
libtool
.libs
@@ -61,6 +62,10 @@ debian/frr.prerm.debhelper
debian/frr.substvars
debian/frr/
debian/tmp/
+*.deb
+*.ddeb
+*.dsc
+*.changes
*.pyc
*.swp
cscope.*
diff --git a/Makefile.am b/Makefile.am
index 15f86dff4f..2468dc733d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,6 +53,7 @@ include nhrpd/subdir.am
include ldpd/subdir.am
include babeld/subdir.am
include eigrpd/subdir.am
+include sharpd/subdir.am
include pimd/subdir.am
SUBDIRS = . @LIBRFP@ @RFPTEST@ \
@@ -64,6 +65,7 @@ DIST_SUBDIRS = . bgpd \
vtysh doc tests \
solaris bgpd/rfp-example/librfp \
bgpd/rfp-example/rfptest \
+ debianpkg \
# end
if PKGSRC
diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c
index e7c27e8e21..8dea1431e2 100644
--- a/babeld/babel_zebra.c
+++ b/babeld/babel_zebra.c
@@ -237,7 +237,7 @@ babel_zebra_connected (struct zclient *zclient)
void babelz_zebra_init(void)
{
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
zclient->zebra_connected = babel_zebra_connected;
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 19cb1cf03a..fa1dcbb762 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -73,6 +73,8 @@ module_LTLIBRARIES =
sbin_PROGRAMS = bgpd
bin_PROGRAMS = bgp_btoa
+BUILT_SOURCES =
+
libbgp_a_SOURCES = \
bgp_memory.c \
bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
@@ -116,13 +118,9 @@ bgpd_snmp_la_LIBADD = ../lib/libfrrsnmp.la
if RPKI
module_LTLIBRARIES += bgpd_rpki.la
+BUILT_SOURCES += bgp_rpki_clippy.c
endif
-bgpd_rpki_la-bgp_rpki.o: bgp_rpki_clippy.c
-bgp_rpki.la: bgp_rpki_clippy.c
-bgp_rpki.lo: bgp_rpki_clippy.c
-bgp_rpki.o: bgp_rpki_clippy.c
-
bgpd_rpki_la_SOURCES = bgp_rpki.c
bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS)
bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index 2c83de89e0..840cc35751 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -239,19 +239,16 @@ void bgp_sync_init(struct peer *peer)
safi_t safi;
struct bgp_synchronize *sync;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- sync = XCALLOC(MTYPE_BGP_SYNCHRONISE,
- sizeof(struct bgp_synchronize));
- BGP_ADV_FIFO_INIT(&sync->update);
- BGP_ADV_FIFO_INIT(&sync->withdraw);
- BGP_ADV_FIFO_INIT(&sync->withdraw_low);
- peer->sync[afi][safi] = sync;
- peer->hash[afi][safi] =
- hash_create(baa_hash_key,
- baa_hash_cmp,
- "BGP Sync Hash");
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ sync = XCALLOC(MTYPE_BGP_SYNCHRONISE,
+ sizeof(struct bgp_synchronize));
+ BGP_ADV_FIFO_INIT(&sync->update);
+ BGP_ADV_FIFO_INIT(&sync->withdraw);
+ BGP_ADV_FIFO_INIT(&sync->withdraw_low);
+ peer->sync[afi][safi] = sync;
+ peer->hash[afi][safi] = hash_create(baa_hash_key, baa_hash_cmp,
+ "BGP Sync Hash");
+ }
}
void bgp_sync_delete(struct peer *peer)
@@ -259,15 +256,13 @@ void bgp_sync_delete(struct peer *peer)
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (peer->sync[afi][safi])
- XFREE(MTYPE_BGP_SYNCHRONISE,
- peer->sync[afi][safi]);
- peer->sync[afi][safi] = NULL;
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->sync[afi][safi])
+ XFREE(MTYPE_BGP_SYNCHRONISE, peer->sync[afi][safi]);
+ peer->sync[afi][safi] = NULL;
- if (peer->hash[afi][safi])
- hash_free(peer->hash[afi][safi]);
- peer->hash[afi][safi] = NULL;
- }
+ if (peer->hash[afi][safi])
+ hash_free(peer->hash[afi][safi]);
+ peer->hash[afi][safi] = NULL;
+ }
}
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 6c03ba3059..caac385fb5 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -479,7 +479,7 @@ unsigned int aspath_has_as4(struct aspath *aspath)
}
/* Convert aspath structure to string expression. */
-static void aspath_make_str_count(struct aspath *as)
+static void aspath_make_str_count(struct aspath *as, bool make_json)
{
struct assegment *seg;
int str_size;
@@ -489,14 +489,18 @@ static void aspath_make_str_count(struct aspath *as)
json_object *jseg = NULL;
json_object *jseg_list = NULL;
- as->json = json_object_new_object();
- jaspath_segments = json_object_new_array();
+ if (make_json) {
+ as->json = json_object_new_object();
+ jaspath_segments = json_object_new_array();
+ }
/* Empty aspath. */
if (!as->segments) {
- json_object_string_add(as->json, "string", "Local");
- json_object_object_add(as->json, "segments", jaspath_segments);
- json_object_int_add(as->json, "length", 0);
+ if (make_json) {
+ json_object_string_add(as->json, "string", "Local");
+ json_object_object_add(as->json, "segments", jaspath_segments);
+ json_object_int_add(as->json, "length", 0);
+ }
as->str = XMALLOC(MTYPE_AS_STR, 1);
as->str[0] = '\0';
as->str_len = 0;
@@ -539,6 +543,7 @@ static void aspath_make_str_count(struct aspath *as)
as->str_len = 0;
json_object_free(as->json);
as->json = NULL;
+
return;
}
@@ -564,12 +569,14 @@ static void aspath_make_str_count(struct aspath *as)
str_buf + len, str_size - len, "%c",
aspath_delimiter_char(seg->type, AS_SEG_START));
- jseg_list = json_object_new_array();
+ if (make_json)
+ jseg_list = json_object_new_array();
/* write out the ASNs, with their seperators, bar the last one*/
for (i = 0; i < seg->length; i++) {
- json_object_array_add(jseg_list,
- json_object_new_int(seg->as[i]));
+ if (make_json)
+ json_object_array_add(jseg_list,
+ json_object_new_int(seg->as[i]));
len += snprintf(str_buf + len, str_size - len, "%u",
seg->as[i]);
@@ -579,11 +586,13 @@ static void aspath_make_str_count(struct aspath *as)
"%c", seperator);
}
- jseg = json_object_new_object();
- json_object_string_add(jseg, "type",
- aspath_segment_type_str[seg->type]);
- json_object_object_add(jseg, "list", jseg_list);
- json_object_array_add(jaspath_segments, jseg);
+ if (make_json) {
+ jseg = json_object_new_object();
+ json_object_string_add(jseg, "type",
+ aspath_segment_type_str[seg->type]);
+ json_object_object_add(jseg, "list", jseg_list);
+ json_object_array_add(jaspath_segments, jseg);
+ }
if (seg->type != AS_SEQUENCE)
len += snprintf(
@@ -601,13 +610,16 @@ static void aspath_make_str_count(struct aspath *as)
as->str = str_buf;
as->str_len = len;
- json_object_string_add(as->json, "string", str_buf);
- json_object_object_add(as->json, "segments", jaspath_segments);
- json_object_int_add(as->json, "length", aspath_count_hops(as));
+ if (make_json) {
+ json_object_string_add(as->json, "string", str_buf);
+ json_object_object_add(as->json, "segments", jaspath_segments);
+ json_object_int_add(as->json, "length", aspath_count_hops(as));
+ }
+
return;
}
-static void aspath_str_update(struct aspath *as)
+void aspath_str_update(struct aspath *as, bool make_json)
{
if (as->str)
XFREE(MTYPE_AS_STR, as->str);
@@ -617,7 +629,7 @@ static void aspath_str_update(struct aspath *as)
as->json = NULL;
}
- aspath_make_str_count(as);
+ aspath_make_str_count(as, make_json);
}
/* Intern allocated AS path. */
@@ -1079,7 +1091,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2)
}
assegment_normalise(aspath->segments);
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
return aspath;
}
@@ -1214,7 +1226,7 @@ struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
seg = seg->next;
}
- aspath_str_update(new);
+ aspath_str_update(new, false);
return new;
}
@@ -1237,7 +1249,7 @@ struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn)
seg = seg->next;
}
- aspath_str_update(new);
+ aspath_str_update(new, false);
return new;
}
@@ -1307,7 +1319,7 @@ struct aspath *aspath_remove_private_asns(struct aspath *aspath)
seg = seg->next;
}
- aspath_str_update(new);
+ aspath_str_update(new, false);
return new;
}
@@ -1362,7 +1374,7 @@ static struct aspath *aspath_merge(struct aspath *as1, struct aspath *as2)
last->next = as2->segments;
as2->segments = new;
- aspath_str_update(as2);
+ aspath_str_update(as2, false);
return as2;
}
@@ -1381,7 +1393,7 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
/* If as2 is empty, only need to dupe as1's chain onto as2 */
if (seg2 == NULL) {
as2->segments = assegment_dup_all(as1->segments);
- aspath_str_update(as2);
+ aspath_str_update(as2, false);
return as2;
}
@@ -1432,7 +1444,7 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
/* we've now prepended as1's segment chain to as2, merging
* the inbetween AS_SEQUENCE of seg2 in the process
*/
- aspath_str_update(as2);
+ aspath_str_update(as2, false);
return as2;
} else {
/* AS_SET merge code is needed at here. */
@@ -1511,7 +1523,7 @@ struct aspath *aspath_filter_exclude(struct aspath *source,
lastseg->next = newseg;
lastseg = newseg;
}
- aspath_str_update(newpath);
+ aspath_str_update(newpath, false);
/* We are happy returning even an empty AS_PATH, because the
* administrator
* might expect this very behaviour. There's a mean to avoid this, if
@@ -1549,7 +1561,7 @@ static struct aspath *aspath_add_asns(struct aspath *aspath, as_t asno,
aspath->segments = newsegment;
}
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
return aspath;
}
@@ -1639,7 +1651,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
if (!hops) {
newpath = aspath_dup(as4path);
- aspath_str_update(newpath);
+ aspath_str_update(newpath, false);
return newpath;
}
@@ -1701,7 +1713,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
mergedpath = aspath_merge(newpath, aspath_dup(as4path));
aspath_free(newpath);
mergedpath->segments = assegment_normalise(mergedpath->segments);
- aspath_str_update(mergedpath);
+ aspath_str_update(mergedpath, false);
if (BGP_DEBUG(as4, AS4))
zlog_debug("[AS4] result of synthesizing is %s",
@@ -1773,7 +1785,7 @@ struct aspath *aspath_delete_confed_seq(struct aspath *aspath)
}
if (removed_confed_segment)
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
return aspath;
}
@@ -1824,7 +1836,7 @@ struct aspath *aspath_empty_get(void)
struct aspath *aspath;
aspath = aspath_new();
- aspath_make_str_count(aspath);
+ aspath_make_str_count(aspath, false);
return aspath;
}
@@ -1975,7 +1987,7 @@ struct aspath *aspath_str2aspath(const char *str)
}
}
- aspath_make_str_count(aspath);
+ aspath_make_str_count(aspath, false);
return aspath;
}
@@ -1987,7 +1999,7 @@ unsigned int aspath_key_make(void *p)
unsigned int key = 0;
if (!aspath->str)
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
key = jhash(aspath->str, aspath->str_len, 2334325);
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index f085cf3cb9..0c065cc936 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -92,6 +92,7 @@ extern struct aspath *aspath_delete_confed_seq(struct aspath *);
extern struct aspath *aspath_empty(void);
extern struct aspath *aspath_empty_get(void);
extern struct aspath *aspath_str2aspath(const char *);
+extern void aspath_str_update(struct aspath *as, bool make_json);
extern void aspath_free(struct aspath *);
extern struct aspath *aspath_intern(struct aspath *);
extern void aspath_unintern(struct aspath **);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 76fc8f968e..6ddb2ec8a7 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -822,6 +822,32 @@ void bgp_attr_unintern_sub(struct attr *attr)
#endif
}
+/*
+ * We have some show commands that let you experimentally
+ * apply a route-map. When we apply the route-map
+ * we are reseting values but not saving them for
+ * posterity via intern'ing( because route-maps don't
+ * do that) but at this point in time we need
+ * to compare the new attr to the old and if the
+ * routemap has changed it we need to, as Snoop Dog says,
+ * Drop it like it's hot
+ */
+void bgp_attr_undup(struct attr *new, struct attr *old)
+{
+ if (new->aspath != old->aspath)
+ aspath_free(new->aspath);
+
+ if (new->community != old->community)
+ community_free(new->community);
+
+ if (new->ecommunity != old->ecommunity)
+ ecommunity_free(&new->ecommunity);
+
+ if (new->lcommunity != old->lcommunity)
+ lcommunity_free(&new->lcommunity);
+
+}
+
/* Free bgp attribute and aspath. */
void bgp_attr_unintern(struct attr **pattr)
{
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 80ff36b59f..f694f01adb 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -239,6 +239,7 @@ extern bgp_attr_parse_ret_t bgp_attr_parse(struct peer *, struct attr *,
bgp_size_t, struct bgp_nlri *,
struct bgp_nlri *);
extern void bgp_attr_dup(struct attr *, struct attr *);
+extern void bgp_attr_undup(struct attr *new, struct attr *old);
extern struct attr *bgp_attr_intern(struct attr *attr);
extern void bgp_attr_unintern_sub(struct attr *);
extern void bgp_attr_unintern(struct attr **);
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index f3bae9535c..72b1098ede 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -438,7 +438,7 @@ static int community_regexp_match(struct community *com, regex_t *reg)
if (com == NULL || com->size == 0)
str = "";
else
- str = community_str(com);
+ str = community_str(com, false);
/* Regular expression match. */
if (regexec(reg, str, 0, NULL, 0) == 0)
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index b0f00d67d6..7c83eaa091 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -169,7 +169,6 @@ struct community *community_uniq_sort(struct community *com)
return NULL;
new = community_new();
- ;
new->json = NULL;
for (i = 0; i < com->size; i++) {
@@ -195,7 +194,7 @@ struct community *community_uniq_sort(struct community *com)
0xFFFF0000 "graceful-shutdown"
For other values, "AS:VAL" format is used. */
-static void set_community_string(struct community *com)
+static void set_community_string(struct community *com, bool make_json)
{
int i;
char *str;
@@ -211,16 +210,20 @@ static void set_community_string(struct community *com)
if (!com)
return;
- com->json = json_object_new_object();
- json_community_list = json_object_new_array();
+ if (make_json) {
+ com->json = json_object_new_object();
+ json_community_list = json_object_new_array();
+ }
/* When communities attribute is empty. */
if (com->size == 0) {
str = XMALLOC(MTYPE_COMMUNITY_STR, 1);
str[0] = '\0';
- json_object_string_add(com->json, "string", "");
- json_object_object_add(com->json, "list", json_community_list);
+ if (make_json) {
+ json_object_string_add(com->json, "string", "");
+ json_object_object_add(com->json, "list", json_community_list);
+ }
com->str = str;
return;
}
@@ -273,47 +276,61 @@ static void set_community_string(struct community *com)
case COMMUNITY_INTERNET:
strcpy(pnt, "internet");
pnt += strlen("internet");
- json_string = json_object_new_string("internet");
- json_object_array_add(json_community_list, json_string);
+ if (make_json) {
+ json_string = json_object_new_string("internet");
+ json_object_array_add(json_community_list, json_string);
+ }
break;
case COMMUNITY_NO_EXPORT:
strcpy(pnt, "no-export");
pnt += strlen("no-export");
- json_string = json_object_new_string("noExport");
- json_object_array_add(json_community_list, json_string);
+ if (make_json) {
+ json_string = json_object_new_string("noExport");
+ json_object_array_add(json_community_list, json_string);
+ }
break;
case COMMUNITY_NO_ADVERTISE:
strcpy(pnt, "no-advertise");
pnt += strlen("no-advertise");
- json_string = json_object_new_string("noAdvertise");
- json_object_array_add(json_community_list, json_string);
+ if (make_json) {
+ json_string = json_object_new_string("noAdvertise");
+ json_object_array_add(json_community_list, json_string);
+ }
break;
case COMMUNITY_LOCAL_AS:
strcpy(pnt, "local-AS");
pnt += strlen("local-AS");
- json_string = json_object_new_string("localAs");
- json_object_array_add(json_community_list, json_string);
+ if (make_json) {
+ json_string = json_object_new_string("localAs");
+ json_object_array_add(json_community_list, json_string);
+ }
break;
case COMMUNITY_GSHUT:
strcpy(pnt, "graceful-shutdown");
pnt += strlen("graceful-shutdown");
- json_string = json_object_new_string("gracefulShutdown");
- json_object_array_add(json_community_list, json_string);
+ if (make_json) {
+ json_string = json_object_new_string("gracefulShutdown");
+ json_object_array_add(json_community_list, json_string);
+ }
break;
default:
as = (comval >> 16) & 0xFFFF;
val = comval & 0xFFFF;
sprintf(pnt, "%u:%d", as, val);
- json_string = json_object_new_string(pnt);
- json_object_array_add(json_community_list, json_string);
+ if (make_json) {
+ json_string = json_object_new_string(pnt);
+ json_object_array_add(json_community_list, json_string);
+ }
pnt += strlen(pnt);
break;
}
}
*pnt = '\0';
- json_object_string_add(com->json, "string", str);
- json_object_object_add(com->json, "list", json_community_list);
+ if (make_json) {
+ json_object_string_add(com->json, "string", str);
+ json_object_object_add(com->json, "list", json_community_list);
+ }
com->str = str;
}
@@ -338,7 +355,7 @@ struct community *community_intern(struct community *com)
/* Make string. */
if (!find->str)
- set_community_string(find);
+ set_community_string(find, false);
return find;
}
@@ -396,13 +413,16 @@ struct community *community_dup(struct community *com)
}
/* Retrun string representation of communities attribute. */
-char *community_str(struct community *com)
+char *community_str(struct community *com, bool make_json)
{
if (!com)
return NULL;
+ if (make_json && !com->json && com->str)
+ XFREE(MTYPE_COMMUNITY_STR, com->str);
+
if (!com->str)
- set_community_string(com);
+ set_community_string(com, make_json);
return com->str;
}
diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h
index f728debdb5..5016f132f2 100644
--- a/bgpd/bgp_community.h
+++ b/bgpd/bgp_community.h
@@ -63,7 +63,7 @@ extern struct community *community_uniq_sort(struct community *);
extern struct community *community_parse(u_int32_t *, u_short);
extern struct community *community_intern(struct community *);
extern void community_unintern(struct community **);
-extern char *community_str(struct community *);
+extern char *community_str(struct community *, bool make_json);
extern unsigned int community_hash_make(struct community *);
extern struct community *community_str2com(const char *);
extern int community_match(const struct community *, const struct community *);
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 6e16d5f45b..45ac8e6859 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -385,7 +385,8 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size)
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
- ", community %s", community_str(attr->community));
+ ", community %s", community_str(attr->community,
+ false));
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index aa350d3dd4..8de7e970de 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -181,22 +181,15 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
from_peer->domainname = NULL;
}
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- peer->af_flags[afi][safi] =
- from_peer->af_flags[afi][safi];
- peer->af_sflags[afi][safi] =
- from_peer->af_sflags[afi][safi];
- peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
- peer->afc_nego[afi][safi] =
- from_peer->afc_nego[afi][safi];
- peer->afc_adv[afi][safi] =
- from_peer->afc_adv[afi][safi];
- peer->afc_recv[afi][safi] =
- from_peer->afc_recv[afi][safi];
- peer->orf_plist[afi][safi] =
- from_peer->orf_plist[afi][safi];
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ peer->af_flags[afi][safi] = from_peer->af_flags[afi][safi];
+ peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
+ peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
+ peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
+ peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
+ peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
+ peer->orf_plist[afi][safi] = from_peer->orf_plist[afi][safi];
+ }
if (bgp_getsockname(peer) < 0) {
zlog_err(
@@ -1070,30 +1063,28 @@ int bgp_stop(struct peer *peer)
peer->fd = -1;
}
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- /* Reset all negotiated variables */
- peer->afc_nego[afi][safi] = 0;
- peer->afc_adv[afi][safi] = 0;
- peer->afc_recv[afi][safi] = 0;
-
- /* peer address family capability flags*/
- peer->af_cap[afi][safi] = 0;
-
- /* peer address family status flags*/
- peer->af_sflags[afi][safi] = 0;
-
- /* Received ORF prefix-filter */
- peer->orf_plist[afi][safi] = NULL;
-
- if ((peer->status == OpenConfirm)
- || (peer->status == Established)) {
- /* ORF received prefix-filter pnt */
- sprintf(orf_name, "%s.%d.%d", peer->host, afi,
- safi);
- prefix_bgp_orf_remove_all(afi, orf_name);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ /* Reset all negotiated variables */
+ peer->afc_nego[afi][safi] = 0;
+ peer->afc_adv[afi][safi] = 0;
+ peer->afc_recv[afi][safi] = 0;
+
+ /* peer address family capability flags*/
+ peer->af_cap[afi][safi] = 0;
+
+ /* peer address family status flags*/
+ peer->af_sflags[afi][safi] = 0;
+
+ /* Received ORF prefix-filter */
+ peer->orf_plist[afi][safi] = NULL;
+
+ if ((peer->status == OpenConfirm)
+ || (peer->status == Established)) {
+ /* ORF received prefix-filter pnt */
+ sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi);
+ prefix_bgp_orf_remove_all(afi, orf_name);
}
+ }
/* Reset keepalive and holdtime */
if (PEER_OR_GROUP_TIMER_SET(peer)) {
@@ -1471,38 +1462,33 @@ static int bgp_establish(struct peer *peer)
peer->uptime = bgp_clock();
/* Send route-refresh when ORF is enabled */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_SM_ADV)) {
if (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_SM_ADV)) {
- if (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_RM_RCV))
- bgp_route_refresh_send(
- peer, afi, safi,
- ORF_TYPE_PREFIX,
- REFRESH_IMMEDIATE, 0);
- else if (
- CHECK_FLAG(
- peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
- bgp_route_refresh_send(
- peer, afi, safi,
- ORF_TYPE_PREFIX_OLD,
- REFRESH_IMMEDIATE, 0);
- }
+ PEER_CAP_ORF_PREFIX_RM_RCV))
+ bgp_route_refresh_send(peer, afi, safi,
+ ORF_TYPE_PREFIX,
+ REFRESH_IMMEDIATE, 0);
+ else if (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
+ bgp_route_refresh_send(peer, afi, safi,
+ ORF_TYPE_PREFIX_OLD,
+ REFRESH_IMMEDIATE, 0);
+ }
+ }
/* First update is deferred until ORF or ROUTE-REFRESH is received */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_RM_ADV))
if (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_RM_ADV))
- if (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_SM_RCV)
- || CHECK_FLAG(
- peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
- SET_FLAG(peer->af_sflags[afi][safi],
- PEER_STATUS_ORF_WAIT_REFRESH);
+ PEER_CAP_ORF_PREFIX_SM_RCV)
+ || CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
+ SET_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_ORF_WAIT_REFRESH);
+ }
bgp_announce_peer(peer);
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 5c9ba89a57..77fb61fbb8 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -1285,59 +1285,52 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
return;
/* MP capability for configured AFI, SAFI */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (peer->afc[afi][safi]) {
- /* Convert AFI, SAFI to values for packet. */
- bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
- &pkt_safi);
-
- peer->afc_adv[afi][safi] = 1;
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc[afi][safi]) {
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
+ &pkt_safi);
+
+ peer->afc_adv[afi][safi] = 1;
+ stream_putc(s, BGP_OPEN_OPT_CAP);
+ stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
+ stream_putc(s, CAPABILITY_CODE_MP);
+ stream_putc(s, CAPABILITY_CODE_MP_LEN);
+ stream_putw(s, pkt_afi);
+ stream_putc(s, 0);
+ stream_putc(s, pkt_safi);
+
+ /* Extended nexthop capability - currently
+ * supporting RFC-5549 for
+ * Link-Local peering only
+ */
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
+ && peer->su.sa.sa_family == AF_INET6
+ && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)
+ && afi == AFI_IP
+ && (safi == SAFI_UNICAST
+ || safi == SAFI_LABELED_UNICAST)) {
+ /* RFC 5549 Extended Next Hop Encoding
+ */
+ SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
stream_putc(s, BGP_OPEN_OPT_CAP);
- stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc(s, CAPABILITY_CODE_MP);
- stream_putc(s, CAPABILITY_CODE_MP_LEN);
+ stream_putc(s, CAPABILITY_CODE_ENHE_LEN + 2);
+ stream_putc(s, CAPABILITY_CODE_ENHE);
+ stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
+
+ SET_FLAG(peer->af_cap[AFI_IP][safi],
+ PEER_CAP_ENHE_AF_ADV);
stream_putw(s, pkt_afi);
- stream_putc(s, 0);
- stream_putc(s, pkt_safi);
+ stream_putw(s, pkt_safi);
+ stream_putw(s, afi_int2iana(AFI_IP6));
- /* Extended nexthop capability - currently
- * supporting RFC-5549 for
- * Link-Local peering only
- */
- if (CHECK_FLAG(peer->flags,
- PEER_FLAG_CAPABILITY_ENHE)
- && peer->su.sa.sa_family == AF_INET6
- && IN6_IS_ADDR_LINKLOCAL(
- &peer->su.sin6.sin6_addr)
- && afi == AFI_IP
- && (safi == SAFI_UNICAST
- || safi == SAFI_LABELED_UNICAST)) {
- /* RFC 5549 Extended Next Hop Encoding
- */
- SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
- stream_putc(s, BGP_OPEN_OPT_CAP);
- stream_putc(s,
- CAPABILITY_CODE_ENHE_LEN
- + 2);
- stream_putc(s, CAPABILITY_CODE_ENHE);
- stream_putc(s,
- CAPABILITY_CODE_ENHE_LEN);
-
- SET_FLAG(peer->af_cap[AFI_IP][safi],
- PEER_CAP_ENHE_AF_ADV);
- stream_putw(s, pkt_afi);
- stream_putw(s, pkt_safi);
- stream_putw(s, afi_int2iana(AFI_IP6));
-
- if (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ENHE_AF_RCV))
- SET_FLAG(
- peer->af_cap[afi][safi],
- PEER_CAP_ENHE_AF_NEGO);
- }
+ if (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ENHE_AF_RCV))
+ SET_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ENHE_AF_NEGO);
}
}
+ }
/* Route refresh. */
SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
@@ -1363,21 +1356,20 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
stream_putl(s, local_as);
/* AddPath */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (peer->afc[afi][safi]) {
- afi_safi_count++;
-
- /* Only advertise addpath TX if a feature that
- * will use it is
- * configured */
- if (CHECK_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_ADDPATH_TX_ALL_PATHS)
- || CHECK_FLAG(
- peer->af_flags[afi][safi],
- PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS))
- adv_addpath_tx = 1;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc[afi][safi]) {
+ afi_safi_count++;
+
+ /* Only advertise addpath TX if a feature that
+ * will use it is
+ * configured */
+ if (CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_ADDPATH_TX_ALL_PATHS)
+ || CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS))
+ adv_addpath_tx = 1;
+ }
+ }
SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
stream_putc(s, BGP_OPEN_OPT_CAP);
@@ -1385,46 +1377,43 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
stream_putc(s, CAPABILITY_CODE_ADDPATH);
stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (peer->afc[afi][safi]) {
- /* Convert AFI, SAFI to values for packet. */
- bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
- &pkt_safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc[afi][safi]) {
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
+ &pkt_safi);
- stream_putw(s, pkt_afi);
- stream_putc(s, pkt_safi);
+ stream_putw(s, pkt_afi);
+ stream_putc(s, pkt_safi);
- if (adv_addpath_tx) {
- stream_putc(s,
- BGP_ADDPATH_RX
- | BGP_ADDPATH_TX);
- SET_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ADDPATH_AF_RX_ADV);
- SET_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ADDPATH_AF_TX_ADV);
- } else {
- stream_putc(s, BGP_ADDPATH_RX);
- SET_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ADDPATH_AF_RX_ADV);
- UNSET_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ADDPATH_AF_TX_ADV);
- }
+ if (adv_addpath_tx) {
+ stream_putc(s, BGP_ADDPATH_RX | BGP_ADDPATH_TX);
+ SET_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV);
+ SET_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV);
+ } else {
+ stream_putc(s, BGP_ADDPATH_RX);
+ SET_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV);
+ UNSET_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV);
}
+ }
+ }
/* ORF capability. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (CHECK_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_ORF_PREFIX_SM)
- || CHECK_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_ORF_PREFIX_RM)) {
- bgp_open_capability_orf(
- s, peer, afi, safi,
- CAPABILITY_CODE_ORF_OLD);
- bgp_open_capability_orf(s, peer, afi, safi,
- CAPABILITY_CODE_ORF);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_ORF_PREFIX_SM)
+ || CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_ORF_PREFIX_RM)) {
+ bgp_open_capability_orf(s, peer, afi, safi,
+ CAPABILITY_CODE_ORF_OLD);
+ bgp_open_capability_orf(s, peer, afi, safi,
+ CAPABILITY_CODE_ORF);
+ }
+ }
/* Dynamic capability. */
if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
@@ -1497,22 +1486,21 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
config
is present */
if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_RESTART)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (peer->afc[afi][safi]) {
- /* Convert AFI, SAFI to values for
- * packet. */
- bgp_map_afi_safi_int2iana(
- afi, safi, &pkt_afi, &pkt_safi);
- stream_putw(s, pkt_afi);
- stream_putc(s, pkt_safi);
- if (bgp_flag_check(
- peer->bgp,
- BGP_FLAG_GR_PRESERVE_FWD))
- stream_putc(s, RESTART_F_BIT);
- else
- stream_putc(s, 0);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc[afi][safi]) {
+ /* Convert AFI, SAFI to values for
+ * packet. */
+ bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
+ &pkt_safi);
+ stream_putw(s, pkt_afi);
+ stream_putc(s, pkt_safi);
+ if (bgp_flag_check(peer->bgp,
+ BGP_FLAG_GR_PRESERVE_FWD))
+ stream_putc(s, RESTART_F_BIT);
+ else
+ stream_putc(s, 0);
+ }
+ }
}
/* Total Graceful restart capability Len. */
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index b7f0114045..a955b3512c 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -204,65 +204,59 @@ static struct stream *bgp_write_packet(struct peer *peer)
if (peer->bgp && peer->bgp->main_peers_update_hold)
return NULL;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- paf = peer_af_find(peer, afi, safi);
- if (!paf || !PAF_SUBGRP(paf))
- continue;
+ FOREACH_AFI_SAFI (afi, safi) {
+ paf = peer_af_find(peer, afi, safi);
+ if (!paf || !PAF_SUBGRP(paf))
+ continue;
+ next_pkt = paf->next_pkt_to_send;
+
+ /* Try to generate a packet for the peer if we are at
+ * the end of
+ * the list. Always try to push out WITHDRAWs first. */
+ if (!next_pkt || !next_pkt->buffer) {
+ next_pkt = subgroup_withdraw_packet(PAF_SUBGRP(paf));
+ if (!next_pkt || !next_pkt->buffer)
+ subgroup_update_packet(PAF_SUBGRP(paf));
next_pkt = paf->next_pkt_to_send;
+ }
- /* Try to generate a packet for the peer if we are at
- * the end of
- * the list. Always try to push out WITHDRAWs first. */
- if (!next_pkt || !next_pkt->buffer) {
- next_pkt = subgroup_withdraw_packet(
- PAF_SUBGRP(paf));
- if (!next_pkt || !next_pkt->buffer)
- subgroup_update_packet(PAF_SUBGRP(paf));
- next_pkt = paf->next_pkt_to_send;
- }
-
- /* If we still don't have a packet to send to the peer,
- * then
- * try to find out out if we have to send eor or if not,
- * skip to
- * the next AFI, SAFI.
- * Don't send the EOR prematurely... if the subgroup's
- * coalesce
- * timer is running, the adjacency-out structure is not
- * created
- * yet.
- */
- if (!next_pkt || !next_pkt->buffer) {
- if (CHECK_FLAG(peer->cap,
- PEER_CAP_RESTART_RCV)) {
- if (!(PAF_SUBGRP(paf))->t_coalesce
- && peer->afc_nego[afi][safi]
- && peer->synctime
- && !CHECK_FLAG(
- peer->af_sflags[afi]
- [safi],
- PEER_STATUS_EOR_SEND)) {
- SET_FLAG(peer->af_sflags[afi]
- [safi],
- PEER_STATUS_EOR_SEND);
- return bgp_update_packet_eor(
- peer, afi, safi);
- }
+ /* If we still don't have a packet to send to the peer,
+ * then
+ * try to find out out if we have to send eor or if not,
+ * skip to
+ * the next AFI, SAFI.
+ * Don't send the EOR prematurely... if the subgroup's
+ * coalesce
+ * timer is running, the adjacency-out structure is not
+ * created
+ * yet.
+ */
+ if (!next_pkt || !next_pkt->buffer) {
+ if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+ if (!(PAF_SUBGRP(paf))->t_coalesce
+ && peer->afc_nego[afi][safi]
+ && peer->synctime
+ && !CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_EOR_SEND)) {
+ SET_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_EOR_SEND);
+ return bgp_update_packet_eor(peer, afi,
+ safi);
}
- continue;
}
+ continue;
+ }
- /*
- * Found a packet template to send, overwrite packet
- * with appropriate
- * attributes from peer and advance peer
- */
- s = bpacket_reformat_for_peer(next_pkt, paf);
- bpacket_queue_advance_peer(paf);
- return s;
- }
+ /*
+ * Found a packet template to send, overwrite packet
+ * with appropriate
+ * attributes from peer and advance peer
+ */
+ s = bpacket_reformat_for_peer(next_pkt, paf);
+ bpacket_queue_advance_peer(paf);
+ return s;
+ }
return NULL;
}
@@ -282,48 +276,44 @@ static void bgp_write_proceed_actions(struct peer *peer)
return;
}
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- paf = peer_af_find(peer, afi, safi);
- if (!paf)
- continue;
- subgrp = paf->subgroup;
- if (!subgrp)
- continue;
+ FOREACH_AFI_SAFI (afi, safi) {
+ paf = peer_af_find(peer, afi, safi);
+ if (!paf)
+ continue;
+ subgrp = paf->subgroup;
+ if (!subgrp)
+ continue;
- next_pkt = paf->next_pkt_to_send;
- if (next_pkt && next_pkt->buffer) {
- BGP_WRITE_ON(peer->t_write, bgp_write,
- peer->fd);
- return;
- }
+ next_pkt = paf->next_pkt_to_send;
+ if (next_pkt && next_pkt->buffer) {
+ BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);
+ return;
+ }
- /* No packets readily available for AFI/SAFI, are there
- * subgroup packets
- * that need to be generated? */
- if (bpacket_queue_is_full(SUBGRP_INST(subgrp),
- SUBGRP_PKTQ(subgrp)))
- fullq_found = 1;
- else if (subgroup_packets_to_build(subgrp)) {
+ /* No packets readily available for AFI/SAFI, are there
+ * subgroup packets
+ * that need to be generated? */
+ if (bpacket_queue_is_full(SUBGRP_INST(subgrp),
+ SUBGRP_PKTQ(subgrp)))
+ fullq_found = 1;
+ else if (subgroup_packets_to_build(subgrp)) {
+ BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);
+ return;
+ }
+
+ /* No packets to send, see if EOR is pending */
+ if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+ if (!subgrp->t_coalesce && peer->afc_nego[afi][safi]
+ && peer->synctime
+ && !CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_EOR_SEND)
+ && safi != SAFI_MPLS_VPN) {
BGP_WRITE_ON(peer->t_write, bgp_write,
peer->fd);
return;
}
-
- /* No packets to send, see if EOR is pending */
- if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
- if (!subgrp->t_coalesce
- && peer->afc_nego[afi][safi]
- && peer->synctime
- && !CHECK_FLAG(peer->af_sflags[afi][safi],
- PEER_STATUS_EOR_SEND)
- && safi != SAFI_MPLS_VPN) {
- BGP_WRITE_ON(peer->t_write, bgp_write,
- peer->fd);
- return;
- }
- }
}
+ }
if (fullq_found) {
BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);
return;
@@ -1300,18 +1290,17 @@ static void bgp_update_explicit_eors(struct peer *peer)
if (bgp_debug_neighbor_events(peer))
zlog_debug("Peer %s: Checking explicit EORs", peer->host);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (peer->afc_nego[afi][safi]
- && !CHECK_FLAG(peer->af_sflags[afi][safi],
- PEER_STATUS_EOR_RECEIVED)) {
- if (bgp_debug_neighbor_events(peer))
- zlog_debug(
- " afi %d safi %d didnt receive EOR",
- afi, safi);
- return;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc_nego[afi][safi]
+ && !CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_EOR_RECEIVED)) {
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ " afi %d safi %d didnt receive EOR",
+ afi, safi);
+ return;
}
+ }
peer->update_delay_over = 1;
peer->bgp->explicit_eors++;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4ee1aafbe9..a655bd0b6f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1157,49 +1157,52 @@ static int bgp_output_modifier(struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi,
const char *rmap_name)
{
- struct bgp_filter *filter;
struct bgp_info info;
route_map_result_t ret;
struct route_map *rmap = NULL;
+ u_char rmap_type;
- filter = &peer->filter[afi][safi];
+ /*
+ * So if we get to this point and have no rmap_name
+ * we want to just show the output as it currently
+ * exists.
+ */
+ if (!rmap_name)
+ return RMAP_PERMIT;
/* Apply default weight value. */
if (peer->weight[afi][safi])
attr->weight = peer->weight[afi][safi];
- if (rmap_name) {
- rmap = route_map_lookup_by_name(rmap_name);
+ rmap = route_map_lookup_by_name(rmap_name);
- if (rmap == NULL)
- return RMAP_DENY;
- } else {
- if (ROUTE_MAP_OUT_NAME(filter)) {
- rmap = ROUTE_MAP_OUT(filter);
-
- if (rmap == NULL)
- return RMAP_DENY;
- }
- }
+ /*
+ * If we have a route map name and we do not find
+ * the routemap that means we have an implicit
+ * deny.
+ */
+ if (rmap == NULL)
+ return RMAP_DENY;
/* Route map apply. */
- if (rmap) {
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
+ /* Duplicate current value to new strucutre for modification. */
+ info.peer = peer;
+ info.attr = attr;
- SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
+ rmap_type = peer->rmap_type;
+ SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply(rmap, p, RMAP_BGP, &info);
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply(rmap, p, RMAP_BGP, &info);
- peer->rmap_type = 0;
+ peer->rmap_type = rmap_type;
+
+ if (ret == RMAP_DENYMATCH)
+ /*
+ * caller has multiple error paths with bgp_attr_flush()
+ */
+ return RMAP_DENY;
- if (ret == RMAP_DENYMATCH)
- /* caller has multiple error paths with bgp_attr_flush()
- */
- return RMAP_DENY;
- }
return RMAP_PERMIT;
}
@@ -2056,12 +2059,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
sizeof(bgp->update_delay_zebra_resume_time));
bgp->main_zebra_update_hold = 0;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (bgp_fibupd_safi(safi))
- bgp_zebra_announce_table(bgp, afi,
- safi);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (bgp_fibupd_safi(safi))
+ bgp_zebra_announce_table(bgp, afi, safi);
+ }
bgp->main_peers_update_hold = 0;
bgp_start_routeadv(bgp);
@@ -3434,9 +3435,8 @@ void bgp_announce_route_all(struct peer *peer)
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_announce_route(peer, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi)
+ bgp_announce_route(peer, afi, safi);
}
static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
@@ -3718,9 +3718,8 @@ void bgp_clear_route_all(struct peer *peer)
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_clear_route(peer, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi)
+ bgp_clear_route(peer, afi, safi);
#if ENABLE_BGP_VNC
rfapiProcessPeerDown(peer);
@@ -4624,30 +4623,28 @@ void bgp_static_add(struct bgp *bgp)
struct bgp_table *table;
struct bgp_static *bgp_static;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
- rn = bgp_route_next(rn)) {
- if (rn->info == NULL)
- continue;
+ FOREACH_AFI_SAFI (afi, safi)
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info == NULL)
+ continue;
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_ENCAP)
- || (safi == SAFI_EVPN)) {
- table = rn->info;
-
- for (rm = bgp_table_top(table); rm;
- rm = bgp_route_next(rm)) {
- bgp_static = rm->info;
- bgp_static_update_safi(
- bgp, &rm->p, bgp_static,
- afi, safi);
- }
- } else {
- bgp_static_update(bgp, &rn->p, rn->info,
- afi, safi);
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ table = rn->info;
+
+ for (rm = bgp_table_top(table); rm;
+ rm = bgp_route_next(rm)) {
+ bgp_static = rm->info;
+ bgp_static_update_safi(bgp, &rm->p,
+ bgp_static, afi,
+ safi);
}
+ } else {
+ bgp_static_update(bgp, &rn->p, rn->info, afi,
+ safi);
}
+ }
}
/* Called from bgp_delete(). Delete all static routes from the BGP
@@ -4661,39 +4658,34 @@ void bgp_static_delete(struct bgp *bgp)
struct bgp_table *table;
struct bgp_static *bgp_static;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
- rn = bgp_route_next(rn)) {
- if (rn->info == NULL)
- continue;
+ FOREACH_AFI_SAFI (afi, safi)
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info == NULL)
+ continue;
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_ENCAP)
- || (safi == SAFI_EVPN)) {
- table = rn->info;
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ table = rn->info;
- for (rm = bgp_table_top(table); rm;
- rm = bgp_route_next(rm)) {
- bgp_static = rm->info;
- bgp_static_withdraw_safi(
- bgp, &rm->p, AFI_IP,
- safi,
- (struct prefix_rd *)&rn
- ->p);
- bgp_static_free(bgp_static);
- rn->info = NULL;
- bgp_unlock_node(rn);
- }
- } else {
- bgp_static = rn->info;
- bgp_static_withdraw(bgp, &rn->p, afi,
- safi);
+ for (rm = bgp_table_top(table); rm;
+ rm = bgp_route_next(rm)) {
+ bgp_static = rm->info;
+ bgp_static_withdraw_safi(
+ bgp, &rm->p, AFI_IP, safi,
+ (struct prefix_rd *)&rn->p);
bgp_static_free(bgp_static);
rn->info = NULL;
bgp_unlock_node(rn);
}
+ } else {
+ bgp_static = rn->info;
+ bgp_static_withdraw(bgp, &rn->p, afi, safi);
+ bgp_static_free(bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node(rn);
}
+ }
}
void bgp_static_redo_import_check(struct bgp *bgp)
@@ -4707,32 +4699,30 @@ void bgp_static_redo_import_check(struct bgp *bgp)
/* Use this flag to force reprocessing of the route */
bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
- rn = bgp_route_next(rn)) {
- if (rn->info == NULL)
- continue;
+ FOREACH_AFI_SAFI (afi, safi) {
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info == NULL)
+ continue;
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_ENCAP)
- || (safi == SAFI_EVPN)) {
- table = rn->info;
-
- for (rm = bgp_table_top(table); rm;
- rm = bgp_route_next(rm)) {
- bgp_static = rm->info;
- bgp_static_update_safi(
- bgp, &rm->p, bgp_static,
- afi, safi);
- }
- } else {
- bgp_static = rn->info;
- bgp_static_update(bgp, &rn->p,
- bgp_static, afi,
- safi);
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ table = rn->info;
+
+ for (rm = bgp_table_top(table); rm;
+ rm = bgp_route_next(rm)) {
+ bgp_static = rm->info;
+ bgp_static_update_safi(bgp, &rm->p,
+ bgp_static, afi,
+ safi);
}
+ } else {
+ bgp_static = rn->info;
+ bgp_static_update(bgp, &rn->p, bgp_static, afi,
+ safi);
}
+ }
+ }
bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
}
@@ -4771,9 +4761,8 @@ void bgp_purge_static_redist_routes(struct bgp *bgp)
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_purge_af_static_redist_routes(bgp, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi)
+ bgp_purge_af_static_redist_routes(bgp, afi, safi);
}
/*
@@ -6148,8 +6137,9 @@ DEFUN (no_ipv6_aggregate_address,
/* Redistribute route treatment. */
void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
- const union g_addr *nexthop, unsigned int ifindex,
- u_int32_t metric, u_char type, u_short instance,
+ const union g_addr *nexthop, ifindex_t ifindex,
+ enum nexthop_types_t nhtype, uint32_t metric,
+ u_char type, u_short instance,
route_tag_t tag)
{
struct bgp_info *new;
@@ -6164,15 +6154,31 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
/* Make default attribute. */
bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
- if (nexthop) {
+
+ switch(nhtype) {
+ case NEXTHOP_TYPE_IFINDEX:
+ break;
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ attr.nexthop = nexthop->ipv4;
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ attr.mp_nexthop_global = nexthop->ipv6;
+ attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
switch (p->family) {
case AF_INET:
- attr.nexthop = nexthop->ipv4;
+ attr.nexthop.s_addr = INADDR_ANY;
break;
case AF_INET6:
- attr.mp_nexthop_global = nexthop->ipv6;
+ memset(&attr.mp_nexthop_global, 0,
+ sizeof(attr.mp_nexthop_global));
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
+ break;
}
+ break;
}
attr.nh_ifindex = ifindex;
@@ -7395,6 +7401,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
/* Line1 display AS-path, Aggregator */
if (attr->aspath) {
if (json_paths) {
+ if (!attr->aspath->json)
+ aspath_str_update(attr->aspath, true);
json_object_lock(attr->aspath->json);
json_object_object_add(json_path, "aspath",
attr->aspath->json);
@@ -7883,6 +7891,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
/* Line 4 display Community */
if (attr->community) {
if (json_paths) {
+ if (!attr->community->json)
+ community_str(attr->community,
+ true);
json_object_lock(attr->community->json);
json_object_object_add(json_path, "community",
attr->community->json);
@@ -8182,8 +8193,6 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
continue;
display = 0;
- if (!first && use_json)
- vty_out(vty, ",");
if (use_json)
json_paths = json_object_new_array();
else
@@ -8379,7 +8388,11 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
inet_ntop(p->family, &p->u.prefix,
buf, BUFSIZ),
p->prefixlen);
- vty_out(vty, "\"%s\": ", buf2);
+ if (first)
+ vty_out(vty, "\"%s\": ", buf2);
+ else
+ vty_out(vty, ",\"%s\": ", buf2);
+
vty_out(vty, "%s",
json_object_to_json_string_ext(json_paths, JSON_C_TO_STRING_PRETTY));
json_object_free(json_paths);
@@ -10170,70 +10183,75 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
}
} else {
for (adj = rn->adj_out; adj; adj = adj->next)
- SUBGRP_FOREACH_PEER (adj->subgroup, paf)
- if (paf->peer == peer) {
- if (header1) {
- if (use_json) {
- json_object_int_add(
- json,
- "bgpTableVersion",
- table->version);
- json_object_string_add(
- json,
- "bgpLocalRouterId",
- inet_ntoa(
- bgp->router_id));
- json_object_object_add(
- json,
- "bgpStatusCodes",
- json_scode);
- json_object_object_add(
- json,
- "bgpOriginCodes",
- json_ocode);
- } else {
- vty_out(vty,
- "BGP table version is %" PRIu64
- ", local router ID is %s\n",
- table->version,
- inet_ntoa(
- bgp->router_id));
- vty_out(vty,
- BGP_SHOW_SCODE_HEADER);
- vty_out(vty,
- BGP_SHOW_OCODE_HEADER);
- }
- header1 = 0;
- }
+ SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
+ if (paf->peer != peer)
+ continue;
- if (header2) {
- if (!use_json)
- vty_out(vty,
- BGP_SHOW_HEADER);
- header2 = 0;
+ if (header1) {
+ if (use_json) {
+ json_object_int_add(
+ json,
+ "bgpTableVersion",
+ table->version);
+ json_object_string_add(
+ json,
+ "bgpLocalRouterId",
+ inet_ntoa(
+ bgp->router_id));
+ json_object_object_add(
+ json,
+ "bgpStatusCodes",
+ json_scode);
+ json_object_object_add(
+ json,
+ "bgpOriginCodes",
+ json_ocode);
+ } else {
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %s\n",
+ table->version,
+ inet_ntoa(
+ bgp->router_id));
+ vty_out(vty,
+ BGP_SHOW_SCODE_HEADER);
+ vty_out(vty,
+ BGP_SHOW_OCODE_HEADER);
}
+ header1 = 0;
+ }
- if (adj->attr) {
- bgp_attr_dup(&attr,
- adj->attr);
- ret = bgp_output_modifier(
- peer, &rn->p,
- &attr, afi,
+ if (header2) {
+ if (!use_json)
+ vty_out(vty,
+ BGP_SHOW_HEADER);
+ header2 = 0;
+ }
+
+ if (adj->attr) {
+ bgp_attr_dup(&attr,
+ adj->attr);
+ ret = bgp_output_modifier(
+ peer, &rn->p,
+ &attr, afi,
+ safi,
+ rmap_name);
+ if (ret != RMAP_DENY) {
+ route_vty_out_tmp(
+ vty,
+ &rn->p,
+ &attr,
safi,
- rmap_name);
- if (ret != RMAP_DENY) {
- route_vty_out_tmp(
- vty,
- &rn->p,
- &attr,
- safi,
- use_json,
- json_ar);
- output_count++;
- } else
- filtered_count++;
- }
+ use_json,
+ json_ar);
+ output_count++;
+ } else
+ filtered_count++;
+
+ bgp_attr_undup(&attr,
+ adj->attr);
}
+ }
}
}
if (use_json)
@@ -11350,10 +11368,8 @@ void bgp_route_init(void)
safi_t safi;
/* Init BGP distance table. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_distance_table[afi][safi] =
- bgp_table_init(afi, safi);
+ FOREACH_AFI_SAFI (afi, safi)
+ bgp_distance_table[afi][safi] = bgp_table_init(afi, safi);
/* IPv4 BGP commands. */
install_element(BGP_NODE, &bgp_table_map_cmd);
@@ -11525,9 +11541,8 @@ void bgp_route_finish(void)
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- bgp_table_unlock(bgp_distance_table[afi][safi]);
- bgp_distance_table[afi][safi] = NULL;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ bgp_table_unlock(bgp_distance_table[afi][safi]);
+ bgp_distance_table[afi][safi] = NULL;
+ }
}
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 6fbeed8963..085de3fabb 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -328,9 +328,11 @@ extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);
extern int bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int);
-extern void bgp_redistribute_add(struct bgp *, struct prefix *,
- const union g_addr *, unsigned int ifindex,
- u_int32_t, u_char, u_short, route_tag_t);
+extern void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
+ const union g_addr *nexthop, ifindex_t ifindex,
+ enum nexthop_types_t nhtype, uint32_t metric,
+ u_char type, u_short instance,
+ route_tag_t tag);
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, u_char,
u_short);
extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, u_short);
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 45487aa003..30397f8487 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -2881,25 +2881,23 @@ static void bgp_route_map_update_peer_group(const char *rmap_name,
/* All the peers have been updated correctly already. This is
* just updating the placeholder data. No real update required.
*/
- for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- filter = &group->conf->filter[afi][safi];
-
- for (direct = RMAP_IN; direct < RMAP_MAX;
- direct++) {
- if ((filter->map[direct].name)
- && (strcmp(rmap_name,
- filter->map[direct].name)
- == 0))
- filter->map[direct].map = map;
- }
-
- if (filter->usmap.name
- && (strcmp(rmap_name, filter->usmap.name)
+ for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &group->conf->filter[afi][safi];
+
+ for (direct = RMAP_IN; direct < RMAP_MAX; direct++) {
+ if ((filter->map[direct].name)
+ && (strcmp(rmap_name,
+ filter->map[direct].name)
== 0))
- filter->usmap.map = map;
+ filter->map[direct].map = map;
}
+
+ if (filter->usmap.name
+ && (strcmp(rmap_name, filter->usmap.name) == 0))
+ filter->usmap.map = map;
+ }
+ }
}
/*
@@ -2930,14 +2928,12 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
continue;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- /* process in/out/import/export/default-orig
- * route-maps */
- bgp_route_map_process_peer(rmap_name, map, peer,
- afi, safi,
- route_update);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ /* process in/out/import/export/default-orig
+ * route-maps */
+ bgp_route_map_process_peer(rmap_name, map, peer, afi,
+ safi, route_update);
+ }
}
/* for outbound/default-orig route-maps, process for groups */
@@ -2947,62 +2943,55 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
/* update peer-group config (template) */
bgp_route_map_update_peer_group(rmap_name, map, bgp);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- /* For table route-map updates. */
- if (!bgp_fibupd_safi(safi))
- continue;
-
- if (bgp->table_map[afi][safi].name
- && (strcmp(rmap_name,
- bgp->table_map[afi][safi].name)
- == 0)) {
- bgp->table_map[afi][safi].map = map;
+ FOREACH_AFI_SAFI (afi, safi) {
+ /* For table route-map updates. */
+ if (!bgp_fibupd_safi(safi))
+ continue;
- if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug(
- "Processing route_map %s update on "
- "table map",
- rmap_name);
- if (route_update)
- bgp_zebra_announce_table(bgp, afi,
- safi);
- }
+ if (bgp->table_map[afi][safi].name
+ && (strcmp(rmap_name, bgp->table_map[afi][safi].name)
+ == 0)) {
+ bgp->table_map[afi][safi].map = map;
+
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug(
+ "Processing route_map %s update on "
+ "table map",
+ rmap_name);
+ if (route_update)
+ bgp_zebra_announce_table(bgp, afi, safi);
+ }
- /* For network route-map updates. */
- for (bn = bgp_table_top(bgp->route[afi][safi]); bn;
- bn = bgp_route_next(bn))
- if ((bgp_static = bn->info) != NULL) {
- if (bgp_static->rmap.name
- && (strcmp(rmap_name,
- bgp_static->rmap.name)
- == 0)) {
- bgp_static->rmap.map = map;
-
- if (route_update)
- if (!bgp_static
- ->backdoor) {
- if (bgp_debug_zebra(
- &bn->p))
- zlog_debug(
- "Processing route_map %s update on "
- "static route %s",
- rmap_name,
- inet_ntop(
- bn->p.family,
- &bn->p.u.prefix,
- buf,
- INET6_ADDRSTRLEN));
- bgp_static_update(
- bgp,
- &bn->p,
- bgp_static,
- afi,
- safi);
- }
- }
+ /* For network route-map updates. */
+ for (bn = bgp_table_top(bgp->route[afi][safi]); bn;
+ bn = bgp_route_next(bn))
+ if ((bgp_static = bn->info) != NULL) {
+ if (bgp_static->rmap.name
+ && (strcmp(rmap_name, bgp_static->rmap.name)
+ == 0)) {
+ bgp_static->rmap.map = map;
+
+ if (route_update)
+ if (!bgp_static->backdoor) {
+ if (bgp_debug_zebra(
+ &bn->p))
+ zlog_debug(
+ "Processing route_map %s update on "
+ "static route %s",
+ rmap_name,
+ inet_ntop(
+ bn->p.family,
+ &bn->p.u.prefix,
+ buf,
+ INET6_ADDRSTRLEN));
+ bgp_static_update(
+ bgp, &bn->p,
+ bgp_static, afi,
+ safi);
+ }
}
- }
+ }
+ }
/* For redistribute route-map updates. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
@@ -3813,7 +3802,7 @@ DEFUN (set_community,
}
/* Set communites attribute string. */
- str = community_str(com);
+ str = community_str(com, false);
if (additive) {
argstr = XCALLOC(MTYPE_TMP,
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index db19835f88..9159bc683d 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1654,15 +1654,13 @@ DEFUN (no_bgp_deterministic_med,
bestpath_per_as_used = 0;
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++)
- if (CHECK_FLAG(
- peer->af_flags[afi][safi],
- PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
- bestpath_per_as_used = 1;
- break;
- }
+ FOREACH_AFI_SAFI (afi, safi)
+ if (CHECK_FLAG(
+ peer->af_flags[afi][safi],
+ PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
+ bestpath_per_as_used = 1;
+ break;
+ }
if (bestpath_per_as_used)
break;
@@ -6315,7 +6313,7 @@ DEFUN (clear_ip_bgp_prefix,
int idx = 0;
/* [<view|vrf> VIEWVRFNAME] */
- if (argv_find(argv, argc, "WORD", &idx))
+ if (argv_find(argv, argc, "VIEWVRFNAME", &idx))
vrf = argv[idx]->arg;
prefix = argv[argc - 1]->arg;
@@ -8403,133 +8401,120 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
json_add = json_object_new_object();
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
- json_object *json_sub =
- NULL;
- json_sub =
- json_object_new_object();
- print_store =
- afi_safi_print(
- afi,
- safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ json_object *json_sub = NULL;
+ json_sub =
+ json_object_new_object();
+ print_store = afi_safi_print(
+ afi, safi);
+ if (CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_RCV)) {
if (CHECK_FLAG(
p->af_cap
[afi]
[safi],
PEER_CAP_ADDPATH_AF_TX_ADV)
- || CHECK_FLAG(
+ && CHECK_FLAG(
p->af_cap
[afi]
[safi],
- PEER_CAP_ADDPATH_AF_TX_RCV)) {
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_ADV)
- && CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_RCV))
- json_object_boolean_true_add(
- json_sub,
- "txAdvertisedAndReceived");
- else if (
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_ADV))
- json_object_boolean_true_add(
- json_sub,
- "txAdvertised");
- else if (
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_RCV))
- json_object_boolean_true_add(
- json_sub,
- "txReceived");
- }
+ PEER_CAP_ADDPATH_AF_TX_RCV))
+ json_object_boolean_true_add(
+ json_sub,
+ "txAdvertisedAndReceived");
+ else if (
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV))
+ json_object_boolean_true_add(
+ json_sub,
+ "txAdvertised");
+ else if (
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_RCV))
+ json_object_boolean_true_add(
+ json_sub,
+ "txReceived");
+ }
+ if (CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_RCV)) {
if (CHECK_FLAG(
p->af_cap
[afi]
[safi],
PEER_CAP_ADDPATH_AF_RX_ADV)
- || CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_RCV)) {
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_ADV)
- && CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_RCV))
- json_object_boolean_true_add(
- json_sub,
- "rxAdvertisedAndReceived");
- else if (
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_ADV))
- json_object_boolean_true_add(
- json_sub,
- "rxAdvertised");
- else if (
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_RCV))
- json_object_boolean_true_add(
- json_sub,
- "rxReceived");
- }
-
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_ADV)
- || CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_RCV)
- || CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_ADV)
- || CHECK_FLAG(
+ && CHECK_FLAG(
p->af_cap
[afi]
[safi],
PEER_CAP_ADDPATH_AF_RX_RCV))
- json_object_object_add(
- json_add,
- print_store,
- json_sub);
- else
- json_object_free(
- json_sub);
+ json_object_boolean_true_add(
+ json_sub,
+ "rxAdvertisedAndReceived");
+ else if (
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV))
+ json_object_boolean_true_add(
+ json_sub,
+ "rxAdvertised");
+ else if (
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_RCV))
+ json_object_boolean_true_add(
+ json_sub,
+ "rxReceived");
}
+ if (CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_RCV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_RCV))
+ json_object_object_add(
+ json_add,
+ print_store,
+ json_sub);
+ else
+ json_object_free(
+ json_sub);
+ }
+
json_object_object_add(
json_cap, "addPath", json_add);
}
@@ -8678,45 +8663,32 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
json_object *json_multi = NULL;
json_multi = json_object_new_object();
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (p->afc_adv[afi][safi]
+ || p->afc_recv[afi][safi]) {
+ json_object *json_exten = NULL;
+ json_exten =
+ json_object_new_object();
+
if (p->afc_adv[afi][safi]
- || p->afc_recv[afi][safi]) {
- json_object
- *json_exten =
- NULL;
- json_exten =
- json_object_new_object();
-
- if (p->afc_adv[afi]
- [safi]
- && p->afc_recv
- [afi]
- [safi])
- json_object_boolean_true_add(
- json_exten,
- "advertisedAndReceived");
- else if (p->afc_adv
- [afi]
- [safi])
- json_object_boolean_true_add(
- json_exten,
- "advertised");
- else if (p->afc_recv
- [afi]
- [safi])
- json_object_boolean_true_add(
- json_exten,
- "received");
+ && p->afc_recv[afi][safi])
+ json_object_boolean_true_add(
+ json_exten,
+ "advertisedAndReceived");
+ else if (p->afc_adv[afi][safi])
+ json_object_boolean_true_add(
+ json_exten,
+ "advertised");
+ else if (p->afc_recv[afi][safi])
+ json_object_boolean_true_add(
+ json_exten,
+ "received");
- json_object_object_add(
- json_multi,
- afi_safi_print(
- afi,
- safi),
- json_exten);
- }
+ json_object_object_add(
+ json_multi,
+ afi_safi_print(afi,
+ safi),
+ json_exten);
}
}
json_object_object_add(
@@ -8798,37 +8770,33 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
"gracefulRestartRemoteTimerMsecs",
p->v_gr_restart * 1000);
- for (afi = AFI_IP;
- afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX;
- safi++) {
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_RESTART_AF_RCV)) {
+ json_object *
+ json_sub =
+ NULL;
+ json_sub =
+ json_object_new_object();
+
if (CHECK_FLAG(
p->af_cap
[afi]
[safi],
- PEER_CAP_RESTART_AF_RCV)) {
- json_object *json_sub =
- NULL;
- json_sub =
- json_object_new_object();
-
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_RESTART_AF_PRESERVE_RCV))
- json_object_boolean_true_add(
- json_sub,
- "preserved");
- restart_af_count++;
- json_object_object_add(
- json_restart,
- afi_safi_print(
- afi,
- safi),
- json_sub);
- }
+ PEER_CAP_RESTART_AF_PRESERVE_RCV))
+ json_object_boolean_true_add(
+ json_sub,
+ "preserved");
+ restart_af_count++;
+ json_object_object_add(
+ json_restart,
+ afi_safi_print(
+ afi,
+ safi),
+ json_sub);
}
}
if (!restart_af_count) {
@@ -8875,101 +8843,93 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
PEER_CAP_ADDPATH_ADV)) {
vty_out(vty, " AddPath:\n");
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_RCV)) {
+ vty_out(vty,
+ " %s: TX ",
+ afi_safi_print(
+ afi,
+ safi));
+
if (CHECK_FLAG(
p->af_cap
[afi]
[safi],
- PEER_CAP_ADDPATH_AF_TX_ADV)
- || CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_RCV)) {
+ PEER_CAP_ADDPATH_AF_TX_ADV))
vty_out(vty,
- " %s: TX ",
+ "advertised %s",
afi_safi_print(
afi,
safi));
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_ADV))
- vty_out(vty,
- "advertised %s",
- afi_safi_print(
- afi,
- safi));
+ if (CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_RCV))
+ vty_out(vty,
+ "%sreceived",
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_TX_ADV)
+ ? " and "
+ : "");
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_RCV))
- vty_out(vty,
- "%sreceived",
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_TX_ADV)
- ? " and "
- : "");
+ vty_out(vty, "\n");
+ }
- vty_out(vty,
- "\n");
- }
+ if (CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV)
+ || CHECK_FLAG(
+ p->af_cap[afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_RCV)) {
+ vty_out(vty,
+ " %s: RX ",
+ afi_safi_print(
+ afi,
+ safi));
if (CHECK_FLAG(
p->af_cap
[afi]
[safi],
- PEER_CAP_ADDPATH_AF_RX_ADV)
- || CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_RCV)) {
+ PEER_CAP_ADDPATH_AF_RX_ADV))
vty_out(vty,
- " %s: RX ",
+ "advertised %s",
afi_safi_print(
afi,
safi));
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_ADV))
- vty_out(vty,
- "advertised %s",
- afi_safi_print(
- afi,
- safi));
-
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_RCV))
- vty_out(vty,
- "%sreceived",
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_ADDPATH_AF_RX_ADV)
- ? " and "
- : "");
-
+ if (CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_RCV))
vty_out(vty,
- "\n");
- }
+ "%sreceived",
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_ADDPATH_AF_RX_ADV)
+ ? " and "
+ : "");
+
+ vty_out(vty, "\n");
}
+ }
}
/* Dynamic */
@@ -9065,30 +9025,25 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
}
/* Multiprotocol Extensions */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++)
- if (p->afc_adv[afi][safi]
- || p->afc_recv[afi][safi]) {
+ FOREACH_AFI_SAFI (afi, safi)
+ if (p->afc_adv[afi][safi]
+ || p->afc_recv[afi][safi]) {
+ vty_out(vty,
+ " Address Family %s:",
+ afi_safi_print(afi,
+ safi));
+ if (p->afc_adv[afi][safi])
vty_out(vty,
- " Address Family %s:",
- afi_safi_print(
- afi,
- safi));
- if (p->afc_adv[afi]
- [safi])
- vty_out(vty,
- " advertised");
- if (p->afc_recv[afi]
- [safi])
- vty_out(vty,
- " %sreceived",
- p->afc_adv[afi]
- [safi]
- ? "and "
- : "");
- vty_out(vty, "\n");
- }
+ " advertised");
+ if (p->afc_recv[afi][safi])
+ vty_out(vty,
+ " %sreceived",
+ p->afc_adv[afi]
+ [safi]
+ ? "and "
+ : "");
+ vty_out(vty, "\n");
+ }
/* Hostname capability */
vty_out(vty, " Hostname Capability:");
@@ -9150,33 +9105,29 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
vty_out(vty,
" Address families by peer:\n ");
- for (afi = AFI_IP;
- afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX;
- safi++)
- if (CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_RESTART_AF_RCV)) {
- vty_out(vty,
- "%s%s(%s)",
- restart_af_count
- ? ", "
- : "",
- afi_safi_print(
- afi,
- safi),
- CHECK_FLAG(
- p->af_cap
- [afi]
- [safi],
- PEER_CAP_RESTART_AF_PRESERVE_RCV)
- ? "preserved"
- : "not preserved");
- restart_af_count++;
- }
+ FOREACH_AFI_SAFI (afi, safi)
+ if (CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_RESTART_AF_RCV)) {
+ vty_out(vty,
+ "%s%s(%s)",
+ restart_af_count
+ ? ", "
+ : "",
+ afi_safi_print(
+ afi,
+ safi),
+ CHECK_FLAG(
+ p->af_cap
+ [afi]
+ [safi],
+ PEER_CAP_RESTART_AF_PRESERVE_RCV)
+ ? "preserved"
+ : "not preserved");
+ restart_af_count++;
+ }
if (!restart_af_count)
vty_out(vty, "none");
vty_out(vty, "\n");
@@ -9201,36 +9152,25 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
json_grace_recv = json_object_new_object();
if (p->status == Established) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
- if (CHECK_FLAG(
- p->af_sflags[afi]
- [safi],
- PEER_STATUS_EOR_SEND)) {
- json_object_boolean_true_add(
- json_grace_send,
- afi_safi_print(
- afi,
- safi));
- eor_send_af_count++;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(p->af_sflags[afi][safi],
+ PEER_STATUS_EOR_SEND)) {
+ json_object_boolean_true_add(
+ json_grace_send,
+ afi_safi_print(afi,
+ safi));
+ eor_send_af_count++;
}
}
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
- if (CHECK_FLAG(
- p->af_sflags[afi]
- [safi],
- PEER_STATUS_EOR_RECEIVED)) {
- json_object_boolean_true_add(
- json_grace_recv,
- afi_safi_print(
- afi,
- safi));
- eor_receive_af_count++;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(
+ p->af_sflags[afi][safi],
+ PEER_STATUS_EOR_RECEIVED)) {
+ json_object_boolean_true_add(
+ json_grace_recv,
+ afi_safi_print(afi,
+ safi));
+ eor_receive_af_count++;
}
}
}
@@ -9261,42 +9201,30 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
vty_out(vty, " Graceful restart informations:\n");
if (p->status == Established) {
vty_out(vty, " End-of-RIB send: ");
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
- if (CHECK_FLAG(
- p->af_sflags[afi]
- [safi],
- PEER_STATUS_EOR_SEND)) {
- vty_out(vty, "%s%s",
- eor_send_af_count
- ? ", "
- : "",
- afi_safi_print(
- afi,
- safi));
- eor_send_af_count++;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(p->af_sflags[afi][safi],
+ PEER_STATUS_EOR_SEND)) {
+ vty_out(vty, "%s%s",
+ eor_send_af_count ? ", "
+ : "",
+ afi_safi_print(afi,
+ safi));
+ eor_send_af_count++;
}
}
vty_out(vty, "\n");
vty_out(vty, " End-of-RIB received: ");
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST;
- safi < SAFI_MAX; safi++) {
- if (CHECK_FLAG(
- p->af_sflags[afi]
- [safi],
- PEER_STATUS_EOR_RECEIVED)) {
- vty_out(vty, "%s%s",
- eor_receive_af_count
- ? ", "
- : "",
- afi_safi_print(
- afi,
- safi));
- eor_receive_af_count++;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (CHECK_FLAG(
+ p->af_sflags[afi][safi],
+ PEER_STATUS_EOR_RECEIVED)) {
+ vty_out(vty, "%s%s",
+ eor_receive_af_count
+ ? ", "
+ : "",
+ afi_safi_print(afi,
+ safi));
+ eor_receive_af_count++;
}
}
vty_out(vty, "\n");
@@ -9424,11 +9352,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
if (use_json)
json_hold = json_object_new_object();
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (p->afc[afi][safi])
- bgp_show_peer_afi(vty, p, afi, safi, use_json,
- json_hold);
+ FOREACH_AFI_SAFI (afi, safi)
+ if (p->afc[afi][safi])
+ bgp_show_peer_afi(vty, p, afi, safi, use_json,
+ json_hold);
if (use_json) {
json_object_object_add(json_neigh, "addressFamilyInfo",
@@ -10010,7 +9937,7 @@ static void community_show_all_iterator(struct hash_backet *backet,
com = (struct community *)backet->data;
vty_out(vty, "[%p] (%ld) %s\n", (void *)com, com->refcnt,
- community_str(com));
+ community_str(com, false));
}
/* Show BGP's community internal data. */
@@ -10479,13 +10406,12 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group)
/* Display AFs configured. */
vty_out(vty, " Configured address-families:");
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (conf->afc[afi][safi]) {
- af_cfgd = 1;
- vty_out(vty, " %s;", afi_safi_print(afi, safi));
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (conf->afc[afi][safi]) {
+ af_cfgd = 1;
+ vty_out(vty, " %s;", afi_safi_print(afi, safi));
}
+ }
if (!af_cfgd)
vty_out(vty, " none\n");
else
@@ -10535,60 +10461,39 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group)
return CMD_SUCCESS;
}
-/* Show BGP peer group's information. */
-enum show_group_type { show_all_groups, show_peer_group };
-
-static int bgp_show_peer_group(struct vty *vty, struct bgp *bgp,
- enum show_group_type type,
- const char *group_name)
+static int bgp_show_peer_group_vty(struct vty *vty, const char *name,
+ const char *group_name)
{
+ struct bgp *bgp;
struct listnode *node, *nnode;
struct peer_group *group;
- int find = 0;
+ bool found = false;
+
+ bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
+
+ if (!bgp) {
+ vty_out(vty, "%% No such BGP instance exists\n");
+ return CMD_WARNING;
+ }
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- switch (type) {
- case show_all_groups:
- bgp_show_one_peer_group(vty, group);
- break;
- case show_peer_group:
- if (group_name
- && (strcmp(group->name, group_name) == 0)) {
- find = 1;
+ if (group_name) {
+ if (strmatch(group->name, group_name)) {
bgp_show_one_peer_group(vty, group);
+ found = true;
+ break;
}
- break;
+ } else {
+ bgp_show_one_peer_group(vty, group);
}
}
- if (type == show_peer_group && !find)
+ if (group_name && !found)
vty_out(vty, "%% No such peer-group\n");
return CMD_SUCCESS;
}
-static int bgp_show_peer_group_vty(struct vty *vty, const char *name,
- enum show_group_type type,
- const char *group_name)
-{
- struct bgp *bgp;
- int ret = CMD_SUCCESS;
-
- if (name)
- bgp = bgp_lookup_by_name(name);
- else
- bgp = bgp_get_default();
-
- if (!bgp) {
- vty_out(vty, "%% No such BGP instance exist\n");
- return CMD_WARNING;
- }
-
- ret = bgp_show_peer_group(vty, bgp, type, group_name);
-
- return ret;
-}
-
DEFUN (show_ip_bgp_peer_groups,
show_ip_bgp_peer_groups_cmd,
"show [ip] bgp [<view|vrf> VIEWVRFNAME] peer-group [PGNAME]",
@@ -10603,10 +10508,10 @@ DEFUN (show_ip_bgp_peer_groups,
vrf = pg = NULL;
int idx = 0;
- vrf = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+ vrf = argv_find(argv, argc, "VIEWVRFNAME", &idx) ? argv[idx]->arg : NULL;
pg = argv_find(argv, argc, "PGNAME", &idx) ? argv[idx]->arg : NULL;
- return bgp_show_peer_group_vty(vty, vrf, show_all_groups, pg);
+ return bgp_show_peer_group_vty(vty, vrf, pg);
}
@@ -12698,7 +12603,7 @@ static void community_list_show(struct vty *vty, struct community_list *list)
vty_out(vty, " %s %s\n",
community_direct_str(entry->direct),
entry->style == COMMUNITY_LIST_STANDARD
- ? community_str(entry->u.com)
+ ? community_str(entry->u.com, false)
: entry->config);
}
}
@@ -13354,7 +13259,7 @@ static const char *community_list_config_str(struct community_entry *entry)
str = "";
else {
if (entry->style == COMMUNITY_LIST_STANDARD)
- str = community_str(entry->u.com);
+ str = community_str(entry->u.com, false);
else
str = entry->config;
}
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index bec7050226..1cf04abfce 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -524,9 +524,10 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient,
static int zebra_read_route(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
+ enum nexthop_types_t nhtype;
struct zapi_route api;
union g_addr nexthop;
- unsigned int ifindex;
+ ifindex_t ifindex;
int add, i;
struct bgp *bgp;
@@ -548,6 +549,7 @@ static int zebra_read_route(int command, struct zclient *zclient,
nexthop = api.nexthops[0].gate;
ifindex = api.nexthops[0].ifindex;
+ nhtype = api.nexthops[0].type;
add = (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
if (add) {
@@ -568,8 +570,8 @@ static int zebra_read_route(int command, struct zclient *zclient,
/* Now perform the add/update. */
bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
- api.metric, api.type, api.instance,
- api.tag);
+ nhtype, api.metric, api.type,
+ api.instance, api.tag);
} else {
bgp_redistribute_delete(bgp, &api.prefix, api.type,
api.instance);
@@ -1757,7 +1759,7 @@ void bgp_zebra_init(struct thread_master *master)
zclient_num_connects = 0;
/* Set default values. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
zclient->zebra_connected = bgp_zebra_connected;
zclient->router_id_update = bgp_router_id_update;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 345ceab9ed..a4952be8a6 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1121,18 +1121,17 @@ struct peer *peer_new(struct bgp *bgp)
peer->password = NULL;
/* Set default flags. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (!bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_COMMUNITY);
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_EXT_COMMUNITY);
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_LARGE_COMMUNITY);
- }
- peer->orf_plist[afi][safi] = NULL;
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (!bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
+ SET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_SEND_COMMUNITY);
+ SET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_SEND_EXT_COMMUNITY);
+ SET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_SEND_LARGE_COMMUNITY);
}
+ peer->orf_plist[afi][safi] = NULL;
+ }
SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
/* Create buffers. */
@@ -1214,16 +1213,13 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
peer_dst->password =
XSTRDUP(MTYPE_PEER_PASSWORD, peer_src->password);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
- peer_dst->af_flags[afi][safi] =
- peer_src->af_flags[afi][safi];
- peer_dst->allowas_in[afi][safi] =
- peer_src->allowas_in[afi][safi];
- peer_dst->weight[afi][safi] =
- peer_src->weight[afi][safi];
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
+ peer_dst->af_flags[afi][safi] = peer_src->af_flags[afi][safi];
+ peer_dst->allowas_in[afi][safi] =
+ peer_src->allowas_in[afi][safi];
+ peer_dst->weight[afi][safi] = peer_src->weight[afi][safi];
+ }
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer_src->peer_af_array[afidx];
@@ -1425,10 +1421,8 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
}
}
@@ -2180,51 +2174,49 @@ int peer_delete(struct peer *peer)
}
/* Free filter related memory. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- filter = &peer->filter[afi][safi];
-
- for (i = FILTER_IN; i < FILTER_MAX; i++) {
- if (filter->dlist[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->dlist[i].name);
- filter->dlist[i].name = NULL;
- }
-
- if (filter->plist[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->plist[i].name);
- filter->plist[i].name = NULL;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &peer->filter[afi][safi];
- if (filter->aslist[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->aslist[i].name);
- filter->aslist[i].name = NULL;
- }
+ for (i = FILTER_IN; i < FILTER_MAX; i++) {
+ if (filter->dlist[i].name) {
+ XFREE(MTYPE_BGP_FILTER_NAME,
+ filter->dlist[i].name);
+ filter->dlist[i].name = NULL;
}
- for (i = RMAP_IN; i < RMAP_MAX; i++) {
- if (filter->map[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->map[i].name);
- filter->map[i].name = NULL;
- }
+ if (filter->plist[i].name) {
+ XFREE(MTYPE_BGP_FILTER_NAME,
+ filter->plist[i].name);
+ filter->plist[i].name = NULL;
}
- if (filter->usmap.name) {
+ if (filter->aslist[i].name) {
XFREE(MTYPE_BGP_FILTER_NAME,
- filter->usmap.name);
- filter->usmap.name = NULL;
+ filter->aslist[i].name);
+ filter->aslist[i].name = NULL;
}
+ }
- if (peer->default_rmap[afi][safi].name) {
- XFREE(MTYPE_ROUTE_MAP_NAME,
- peer->default_rmap[afi][safi].name);
- peer->default_rmap[afi][safi].name = NULL;
+ for (i = RMAP_IN; i < RMAP_MAX; i++) {
+ if (filter->map[i].name) {
+ XFREE(MTYPE_BGP_FILTER_NAME,
+ filter->map[i].name);
+ filter->map[i].name = NULL;
}
}
+ if (filter->usmap.name) {
+ XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
+ filter->usmap.name = NULL;
+ }
+
+ if (peer->default_rmap[afi][safi].name) {
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ peer->default_rmap[afi][safi].name);
+ peer->default_rmap[afi][safi].name = NULL;
+ }
+ }
+
FOREACH_AFI_SAFI (afi, safi)
peer_af_delete(peer, afi, safi);
@@ -2622,19 +2614,17 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
if (peer->conf_if && cap_enhe_preset)
peer_flag_set(peer, PEER_FLAG_CAPABILITY_ENHE);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (group->conf->afc[afi][safi]) {
- peer->afc[afi][safi] = 1;
-
- if (peer_af_find(peer, afi, safi)
- || peer_af_create(peer, afi,
- safi)) {
- peer_group2peer_config_copy_af(
- group, peer, afi, safi);
- }
- } else if (peer->afc[afi][safi])
- peer_deactivate(peer, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (group->conf->afc[afi][safi]) {
+ peer->afc[afi][safi] = 1;
+
+ if (peer_af_find(peer, afi, safi)
+ || peer_af_create(peer, afi, safi)) {
+ peer_group2peer_config_copy_af(
+ group, peer, afi, safi);
+ }
+ } else if (peer->afc[afi][safi])
+ peer_deactivate(peer, afi, safi);
}
if (peer->group) {
@@ -2704,15 +2694,15 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
/* If the peer-group is active for this afi/safi then activate
* for this peer */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (group->conf->afc[afi][safi]) {
- peer->afc[afi][safi] = 1;
- peer_af_create(peer, afi, safi);
- peer_group2peer_config_copy_af(
- group, peer, afi, safi);
- } else if (peer->afc[afi][safi])
- peer_deactivate(peer, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (group->conf->afc[afi][safi]) {
+ peer->afc[afi][safi] = 1;
+ peer_af_create(peer, afi, safi);
+ peer_group2peer_config_copy_af(group, peer, afi,
+ safi);
+ } else if (peer->afc[afi][safi])
+ peer_deactivate(peer, afi, safi);
+ }
SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
@@ -2734,19 +2724,18 @@ int peer_group_unbind(struct bgp *bgp, struct peer *peer,
if (group != peer->group)
return BGP_ERR_PEER_GROUP_MISMATCH;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (peer->afc[afi][safi]) {
- peer->afc[afi][safi] = 0;
- peer_af_flag_reset(peer, afi, safi);
-
- if (peer_af_delete(peer, afi, safi) != 0) {
- zlog_err(
- "couldn't delete af structure for peer %s",
- peer->host);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc[afi][safi]) {
+ peer->afc[afi][safi] = 0;
+ peer_af_flag_reset(peer, afi, safi);
+
+ if (peer_af_delete(peer, afi, safi) != 0) {
+ zlog_err(
+ "couldn't delete af structure for peer %s",
+ peer->host);
}
}
+ }
assert(listnode_lookup(group->peer, peer));
peer_unlock(peer); /* peer group list reference */
@@ -2846,18 +2835,17 @@ static struct bgp *bgp_create(as_t *as, const char *name,
bgp->group = list_new();
bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- bgp->route[afi][safi] = bgp_table_init(afi, safi);
- bgp->aggregate[afi][safi] = bgp_table_init(afi, safi);
- bgp->rib[afi][safi] = bgp_table_init(afi, safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ bgp->route[afi][safi] = bgp_table_init(afi, safi);
+ bgp->aggregate[afi][safi] = bgp_table_init(afi, safi);
+ bgp->rib[afi][safi] = bgp_table_init(afi, safi);
- /* Enable maximum-paths */
- bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
- multipath_num, 0);
- bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
- multipath_num, 0);
- }
+ /* Enable maximum-paths */
+ bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
+ multipath_num, 0);
+ bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
+ multipath_num, 0);
+ }
bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
@@ -3206,27 +3194,26 @@ void bgp_free(struct bgp *bgp)
bgp->peerhash = NULL;
}
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- /* Special handling for 2-level routing tables. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
- || safi == SAFI_EVPN) {
- for (rn = bgp_table_top(bgp->rib[afi][safi]);
- rn; rn = bgp_route_next(rn)) {
- table = (struct bgp_table *)rn->info;
- bgp_table_finish(&table);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ /* Special handling for 2-level routing tables. */
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN) {
+ for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ table = (struct bgp_table *)rn->info;
+ bgp_table_finish(&table);
}
- if (bgp->route[afi][safi])
- bgp_table_finish(&bgp->route[afi][safi]);
- if (bgp->aggregate[afi][safi])
- bgp_table_finish(&bgp->aggregate[afi][safi]);
- if (bgp->rib[afi][safi])
- bgp_table_finish(&bgp->rib[afi][safi]);
- rmap = &bgp->table_map[afi][safi];
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
}
+ if (bgp->route[afi][safi])
+ bgp_table_finish(&bgp->route[afi][safi]);
+ if (bgp->aggregate[afi][safi])
+ bgp_table_finish(&bgp->aggregate[afi][safi]);
+ if (bgp->rib[afi][safi])
+ bgp_table_finish(&bgp->rib[afi][safi]);
+ rmap = &bgp->table_map[afi][safi];
+ if (rmap->name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ }
bgp_scan_finish(bgp);
bgp_address_destroy(bgp);
@@ -3360,17 +3347,16 @@ struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
* peer_group_bind as that is sub-optimal and does some stuff we don't
* want.
*/
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (!group->conf->afc[afi][safi])
- continue;
- peer->afc[afi][safi] = 1;
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (!group->conf->afc[afi][safi])
+ continue;
+ peer->afc[afi][safi] = 1;
- if (!peer_af_find(peer, afi, safi))
- peer_af_create(peer, afi, safi);
+ if (!peer_af_find(peer, afi, safi))
+ peer_af_create(peer, afi, safi);
- peer_group2peer_config_copy_af(group, peer, afi, safi);
- }
+ peer_group2peer_config_copy_af(group, peer, afi, safi);
+ }
/* Mark as dynamic, but also as a "config node" for other things to
* work. */
@@ -5237,45 +5223,40 @@ static void peer_distribute_update(struct access_list *access)
update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
access->name, 0, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter = &peer->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->dlist[direct].name)
- filter->dlist[direct]
- .alist = access_list_lookup(
- afi,
- filter->dlist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &peer->filter[afi][safi];
+
+ for (direct = FILTER_IN; direct < FILTER_MAX;
+ direct++) {
+ if (filter->dlist[direct].name)
+ filter->dlist[direct]
+ .alist = access_list_lookup(
+ afi,
filter->dlist[direct]
- .alist = NULL;
- }
+ .name);
+ else
+ filter->dlist[direct].alist =
+ NULL;
}
+ }
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter =
- &group->conf->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->dlist[direct].name)
- filter->dlist[direct]
- .alist = access_list_lookup(
- afi,
- filter->dlist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &group->conf->filter[afi][safi];
+
+ for (direct = FILTER_IN; direct < FILTER_MAX;
+ direct++) {
+ if (filter->dlist[direct].name)
+ filter->dlist[direct]
+ .alist = access_list_lookup(
+ afi,
filter->dlist[direct]
- .alist = NULL;
- }
+ .name);
+ else
+ filter->dlist[direct].alist =
+ NULL;
}
+ }
}
#if ENABLE_BGP_VNC
vnc_prefix_list_update(bgp);
@@ -5408,45 +5389,40 @@ static void peer_prefix_list_update(struct prefix_list *plist)
plist ? prefix_list_name(plist) : NULL, 0, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter = &peer->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->plist[direct].name)
- filter->plist[direct]
- .plist = prefix_list_lookup(
- afi,
- filter->plist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &peer->filter[afi][safi];
+
+ for (direct = FILTER_IN; direct < FILTER_MAX;
+ direct++) {
+ if (filter->plist[direct].name)
+ filter->plist[direct]
+ .plist = prefix_list_lookup(
+ afi,
filter->plist[direct]
- .plist = NULL;
- }
+ .name);
+ else
+ filter->plist[direct].plist =
+ NULL;
}
+ }
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter =
- &group->conf->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->plist[direct].name)
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &group->conf->filter[afi][safi];
+
+ for (direct = FILTER_IN; direct < FILTER_MAX;
+ direct++) {
+ if (filter->plist[direct].name)
+ filter->plist[direct]
+ .plist = prefix_list_lookup(
+ afi,
filter->plist[direct]
- .plist = prefix_list_lookup(
- afi,
- filter->plist[direct]
- .name);
- else
- filter->plist[direct]
- .plist = NULL;
- }
+ .name);
+ else
+ filter->plist[direct].plist =
+ NULL;
}
+ }
}
}
}
@@ -5565,43 +5541,38 @@ static void peer_aslist_update(const char *aslist_name)
aslist_name, 0, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter = &peer->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->aslist[direct].name)
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &peer->filter[afi][safi];
+
+ for (direct = FILTER_IN; direct < FILTER_MAX;
+ direct++) {
+ if (filter->aslist[direct].name)
+ filter->aslist[direct]
+ .aslist = as_list_lookup(
filter->aslist[direct]
- .aslist = as_list_lookup(
- filter->aslist[direct]
- .name);
- else
- filter->aslist[direct]
- .aslist = NULL;
- }
+ .name);
+ else
+ filter->aslist[direct].aslist =
+ NULL;
}
+ }
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter =
- &group->conf->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->aslist[direct].name)
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &group->conf->filter[afi][safi];
+
+ for (direct = FILTER_IN; direct < FILTER_MAX;
+ direct++) {
+ if (filter->aslist[direct].name)
+ filter->aslist[direct]
+ .aslist = as_list_lookup(
filter->aslist[direct]
- .aslist = as_list_lookup(
- filter->aslist[direct]
- .name);
- else
- filter->aslist[direct]
- .aslist = NULL;
- }
+ .name);
+ else
+ filter->aslist[direct].aslist =
+ NULL;
}
+ }
}
}
}
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index 478d3b5ac7..5c71df238f 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -892,7 +892,7 @@ extern struct zebra_privs_t bgpd_privs;
void vnc_zebra_init(struct thread_master *master)
{
/* Set default values. */
- zclient_vnc = zclient_new(master);
+ zclient_vnc = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs);
zclient_vnc->redistribute_route_add = vnc_zebra_read_route;
diff --git a/configure.ac b/configure.ac
index 41ebab6a16..16cc8901a3 100755
--- a/configure.ac
+++ b/configure.ac
@@ -201,6 +201,7 @@ else
fi
fi
AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"])
+AM_CONDITIONAL([SHARPD], [test "x$enable_dev_build" = "xyes"])
dnl always want these CFLAGS
AC_C_FLAG([-fno-omit-frame-pointer])
@@ -381,6 +382,8 @@ AC_ARG_ENABLE(cumulus,
AS_HELP_STRING([--enable-cumulus], [enable Cumulus Switch Special Extensions]))
AC_ARG_ENABLE(datacenter,
AS_HELP_STRING([--enable-datacenter], [enable Compilation for Data Center Extensions]))
+AC_ARG_ENABLE(fuzzing,
+ AS_HELP_STRING([--enable-fuzzing], [enable ability to fuzz various parts of FRR]))
AC_ARG_ENABLE(rr-semantics,
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_ARG_ENABLE([protobuf],
@@ -434,6 +437,10 @@ else
DFLT_NAME="traditional"
fi
+if test "${enable_fuzzing}" = "yes" ; then
+ AC_DEFINE(HANDLE_ZAPI_FUZZING,,Compile extensions to use with a fuzzer)
+fi
+
if test "${enable_cumulus}" = "yes" ; then
AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
fi
@@ -1839,6 +1846,8 @@ AC_CONFIG_FILES([Makefile
doc/Makefile tests/Makefile
bgpd/rfp-example/rfptest/Makefile bgpd/rfp-example/librfp/Makefile
redhat/frr.spec
+ debianpkg/Makefile
+ debianpkg/changelog
snapcraft/snapcraft.yaml
lib/version.h
tests/lib/cli/test_cli.refout
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 84b04c347d..0000000000
--- a/debian/control
+++ /dev/null
@@ -1,48 +0,0 @@
-Source: frr
-Section: net
-Priority: optional
-Maintainer: Christian Hammers <ch@debian.org>
-Uploaders: Florian Weimer <fw@debian.org>
-Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, po-debconf, autotools-dev, hardening-wrapper, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, dh-systemd, libsystemd-dev, python-ipaddr, bison, flex, libc-ares-dev, python3-dev
-Standards-Version: 3.9.6
-Homepage: http://www.frr.net/
-XS-Testsuite: autopkgtest
-
-Package: frr
-Architecture: any
-Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute2 | iproute, ${misc:Depends}, libc-ares2
-Pre-Depends: adduser
-Conflicts: zebra, zebra-pj, quagga
-Replaces: zebra, zebra-pj
-Suggests: snmpd
-Description: BGP/OSPF/RIP routing daemon
- Frr is free software which manages TCP/IP based routing protocols.
- It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, and RIPng as
- well as the IPv6 versions of these.
- .
- Frr uses threading if the kernel supports it, but can also run on
- kernels that do not support threading. Each protocol has its own daemon.
- .
- It is more than a routed replacement, it can be used as a Route Server and
- a Route Reflector.
-
-Package: frr-dbg
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version})
-Priority: extra
-Section: debug
-Description: BGP/OSPF/RIP routing daemon (debug symbols)
- This package provides debugging symbols for all binary packages built from
- frr source package. It's highly recommended to have this package installed
- before reporting any Frr crashes to either Frr developers or Debian
- package maintainers.
-
-Package: frr-doc
-Section: net
-Architecture: all
-Depends: ${misc:Depends}
-Suggests: frr
-Description: documentation files for frr
- This package includes info files for frr, a free software which manages
- TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
- IS-IS, RIPv1, RIPv2, and RIPng as well as the IPv6 versions of these.
diff --git a/debian/frr-doc.install b/debian/frr-doc.install
deleted file mode 100644
index d2d3f1bbd9..0000000000
--- a/debian/frr-doc.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/share/info
diff --git a/debian/frr.config b/debian/frr.config
deleted file mode 100644
index f642bea1d5..0000000000
--- a/debian/frr.config
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash -e
-
-. /usr/share/debconf/confmodule
-
diff --git a/debian/patches/50_vtysh__vtysh.conf.sample.diff b/debian/patches/50_vtysh__vtysh.conf.sample.diff
deleted file mode 100644
index d60581f70c..0000000000
--- a/debian/patches/50_vtysh__vtysh.conf.sample.diff
+++ /dev/null
@@ -1,16 +0,0 @@
-Description: Change example to make it compatible with the Debian init scripts
- per default.
-Author: Christian Hammers <ch@debian.org>
-
---- old/vtysh/vtysh.conf.sample.orig 2004-10-30 23:07:40.000000000 +0200
-+++ new/vtysh/vtysh.conf.sample 2004-10-30 23:08:24.000000000 +0200
-@@ -1,7 +1,7 @@
- !
- ! Sample configuration file for vtysh.
- !
--!service integrated-vtysh-config
-+service integrated-vtysh-config
- !hostname quagga-router
--!username root nopassword
-+username root nopassword
- !
diff --git a/debian/patches/75_vtysh__vtysh.c__PAGER.diff b/debian/patches/75_vtysh__vtysh.c__PAGER.diff
deleted file mode 100644
index 2dbf6b2441..0000000000
--- a/debian/patches/75_vtysh__vtysh.c__PAGER.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-Description: Use the pager program that was choosen with the Debian
- update-alternative system. (Updated line numbers for 0.99.22)
-Author: Christian Hammers <ch@debian.org>
-
---- old/vtysh/vtysh.c.orig 2004-10-18 01:23:16.000000000 +0200
-+++ new/vtysh/vtysh.c 2004-10-18 01:25:15.000000000 +0200
-@@ -265,10 +265,16 @@
-
- pager_defined = getenv ("VTYSH_PAGER");
-
-- if (pager_defined)
-+ if (pager_defined) {
- vtysh_pager_name = strdup (pager_defined);
-- else
-- vtysh_pager_name = strdup ("more");
-+ } else {
-+ struct stat pager_stat;
-+ if (stat("/usr/bin/pager", &pager_stat) == 0) {
-+ vtysh_pager_name = strdup ("/usr/bin/pager");
-+ } else {
-+ vtysh_pager_name = strdup ("more");
-+ }
-+ }
- }
-
- /* Command execution over the vty interface. */
diff --git a/debian/patches/80_vtysh__vtysh.c__privs.diff b/debian/patches/80_vtysh__vtysh.c__privs.diff
deleted file mode 100644
index 863c81391f..0000000000
--- a/debian/patches/80_vtysh__vtysh.c__privs.diff
+++ /dev/null
@@ -1,59 +0,0 @@
-Description: Fixes group permission. (line numbers adjusted for 0.99.22)
-
-Index: quagga-0.99.23.1/vtysh/vtysh.c
-===================================================================
---- quagga-0.99.23.1.orig/vtysh/vtysh.c 2015-04-16 07:58:08.000000000 -0700
-+++ quagga-0.99.23.1/vtysh/vtysh.c 2015-04-16 08:02:16.108035000 -0700
-@@ -26,6 +26,8 @@
- #include <sys/wait.h>
- #include <sys/resource.h>
- #include <sys/stat.h>
-+#include <sys/types.h>
-+#include <grp.h>
-
- #include <readline/readline.h>
- #include <readline/history.h>
-@@ -2026,6 +2028,9 @@
- char line[] = "write terminal\n";
- FILE *fp, *fp1;
-
-+ /* Setting file permissions */
-+ struct group *quagga_vty_group;
-+
- fprintf (stdout,"Building Configuration...\n");
-
- backup_config_file(integrate_default);
-@@ -2058,16 +2063,31 @@
-
- fclose (fp);
-
-+ errno = 0;
-+ if ((quagga_vty_group = getgrnam(VTY_GROUP)) == NULL)
-+ {
-+ fprintf (stdout, "%% Can't get group %s: %s (%d)\n",
-+ VTY_GROUP, strerror(errno), errno);
-+ return CMD_WARNING;
-+ }
-+
-+ if ((chown(integrate_default, -1, quagga_vty_group->gr_gid)) != 0)
-+ {
-+ fprintf (stdout,"%% Can't chown configuration file %s: %s (%d)\n",
-+ integrate_default, strerror(errno), errno);
-+ return CMD_WARNING;
-+ }
-+
- if (chmod (integrate_default, CONFIGFILE_MASK) != 0)
- {
-- fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
-+ fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
- integrate_default, safe_strerror(errno), errno);
- return CMD_WARNING;
- }
-
- if (chmod (host.config, CONFIGFILE_MASK) != 0)
- {
-- fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
-+ fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
- integrate_default, safe_strerror(errno), errno);
- return CMD_WARNING;
- }
diff --git a/debian/patches/82_vtysh__vtysh_user.c__pam.diff b/debian/patches/82_vtysh__vtysh_user.c__pam.diff
deleted file mode 100644
index 5358ed8870..0000000000
--- a/debian/patches/82_vtysh__vtysh_user.c__pam.diff
+++ /dev/null
@@ -1,10 +0,0 @@
-Description: Adds explanation why vtysh does not work if PAM fails.
-Author: Christian Hammers <ch@debian.org>
-
---- old/vtysh/vtysh_user.c.orig 2006-11-03 01:53:58.000000000 +0100
-+++ new/vtysh/vtysh_user.c 2006-11-03 01:59:02.000000000 +0100
-@@ -60,2 +60,4 @@ vtysh_pam (const char *user)
- ret = pam_authenticate (pamh, 0);
-+ if (ret != PAM_SUCCESS)
-+ printf("Not authenticated. Check /etc/pam.d/quagga.\n");
- /* printf ("ret %d\n", ret); */
diff --git a/debian/patches/90_configure_ncurses.diff b/debian/patches/90_configure_ncurses.diff
deleted file mode 100644
index 9d3dbb15d1..0000000000
--- a/debian/patches/90_configure_ncurses.diff
+++ /dev/null
@@ -1,47 +0,0 @@
-Description: To make checklib happy.
- See http://rerun.lefant.net/checklib/log.quagga_0.99.5-1.html
- (adjusted for 0.99.2)
-Author: Christian Hammers <ch@debian.org>
-
---- old/configure 2011-09-27 00:30:23.000000000 +0200
-+++ new/configure 2011-09-27 00:30:28.000000000 +0200
-@@ -14207,7 +14207,8 @@
- $as_echo_n "(cached) " >&6
- else
- ac_check_lib_save_LIBS=$LIBS
--LIBS="-ltermcap $LIBS"
-+#42#DEBIAN# LIBS="-ltermcap $LIBS"
-+LIBS="$LIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h. */
-
-@@ -14238,7 +14238,8 @@
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tputs" >&5
- $as_echo "$ac_cv_lib_termcap_tputs" >&6; }
- if test "x$ac_cv_lib_termcap_tputs" = xyes; then :
-- LIBREADLINE="$LIBREADLINE -ltermcap"
-+ #42#DEBIAN# LIBREADLINE="$LIBREADLINE -ltermcap"
-+ LIBREADLINE="$LIBREADLINE "
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tputs in -ltinfo" >&5
- $as_echo_n "checking for tputs in -ltinfo... " >&6; }
-@@ -14285,7 +14289,8 @@
- $as_echo_n "(cached) " >&6
- else
- ac_check_lib_save_LIBS=$LIBS
--LIBS="-lcurses $LIBS"
-+#42#DEBIAN# LIBS="-lcurses $LIBS"
-+LIBS="$LIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h. */
-
-@@ -14355,7 +14355,8 @@
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tputs" >&5
- $as_echo "$ac_cv_lib_ncurses_tputs" >&6; }
- if test "x$ac_cv_lib_ncurses_tputs" = xyes; then :
-- LIBREADLINE="$LIBREADLINE -lncurses"
-+ #42#DEBIAN# LIBREADLINE="$LIBREADLINE -lncurses"
-+ LIBREADLINE="$LIBREADLINE"
- fi
-
-
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index b3f6cc1452..0000000000
--- a/debian/patches/series
+++ /dev/null
@@ -1,5 +0,0 @@
-90_configure_ncurses.diff
-82_vtysh__vtysh_user.c__pam.diff
-80_vtysh__vtysh.c__privs.diff
-75_vtysh__vtysh.c__PAGER.diff
-50_vtysh__vtysh.conf.sample.diff
diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in
deleted file mode 100644
index 04d24252cd..0000000000
--- a/debian/po/POTFILES.in
+++ /dev/null
@@ -1 +0,0 @@
-[type: gettext/rfc822deb] quagga.templates
diff --git a/debian/po/cs.po b/debian/po/cs.po
deleted file mode 100644
index df4f47d914..0000000000
--- a/debian/po/cs.po
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2005-07-13 18:52+0200\n"
-"Last-Translator: Miroslav Kure <kurem@debian.cz>\n"
-"Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n"
-"Language: cs\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Opravdu chcete zastavit daemon Quagga?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"VAROVÃNÃ: Abyste mohli pokraÄovat, musí se smÄ›rovací daemon Quagga "
-"pozastavit. To může vést ke zpanikaření BGP nebo ke ztrátě konektivity."
diff --git a/debian/po/da.po b/debian/po/da.po
deleted file mode 100644
index 22b2d56c66..0000000000
--- a/debian/po/da.po
+++ /dev/null
@@ -1,33 +0,0 @@
-# Danish translation quagga.
-# Copyright (C) 2010 quagga & nedenstående oversættere.
-# This file is distributed under the same license as the quagga package.
-# Joe Hansen <joedalton2@yahoo.dk>, 2010.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2010-09-09 23:51+0200\n"
-"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
-"Language-Team: Danish <debian-l10n-danish@lists.debian.org> \n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Ønsker du virkelig at stoppe dæmonen Quagga?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"ADVARSEL: Ruteplanlægningsdæmonen Quagga skal stoppes for at fortsætte. "
-"Dette kan føre til BGP-udfald eller tab af netværksforbindelse."
diff --git a/debian/po/de.po b/debian/po/de.po
deleted file mode 100644
index cbf919e2e5..0000000000
--- a/debian/po/de.po
+++ /dev/null
@@ -1,34 +0,0 @@
-# translation of po-debconf template to German
-# Copyright (C) 2007, Matthias Julius
-# This file is distributed under the same license as the quagga package.
-#
-# Matthias Julius <mdeb@julius-net.net>, 2007.
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga 0.99.6-2\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2007-02-01 19:32-0500\n"
-"Last-Translator: Matthias Julius <mdeb@julius-net.net>\n"
-"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
-"Language: de\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Möchten Sie den Quagga-Daemon wirklich beenden?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"Warnung: Um fortzufahren muss der Quagga-Routing-Daemon beendet werden. Dies "
-"könnte zu BGP-Flaps oder Verlust der Netzwerkverbindung führen."
diff --git a/debian/po/es.po b/debian/po/es.po
deleted file mode 100644
index 3b9e421a48..0000000000
--- a/debian/po/es.po
+++ /dev/null
@@ -1,57 +0,0 @@
-# quagga translation to spanish
-# Copyright (C) 2004 Software in the Public Interest
-# This file is distributed under the same license as the quagga package.
-#
-# Changes:
-# - Initial translation
-# Carlos Galisteo de Cabo <cgalisteo@k-rolus.net>, 2007
-#
-#
-# Traductores, si no conoce el formato PO, merece la pena leer la
-# documentación de gettext, especialmente las secciones dedicadas a este
-# formato, por ejemplo ejecutando:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Equipo de traducción al español, por favor lean antes de traducir
-# los siguientes documentos:
-#
-# - El proyecto de traducción de Debian al español
-# http://www.debian.org/intl/spanish/coordinacion
-# especialmente las notas de traducción en
-# http://www.debian.org/intl/spanish/notas
-#
-# - La guía de traducción de po's de debconf:
-# /usr/share/doc/po-debconf/README-trans
-# o http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga_0.99.7-2\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2007-05-08 12:39+0200\n"
-"Last-Translator: Carlos Galisteo <cgalisteo@k-rolus.net>\n"
-"Language-Team: <debian-l10n-spanish@lists.debian.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-15\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "¿Está seguro de que quiere detener el servicio «Quagga»?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"ADVERTENCIA: Debe detenerse el servicio de encaminamiento «Quagga» para "
-"continuar. Ésto podría provocar intermitencias en BGP o pérdidas de "
-"conectividad."
diff --git a/debian/po/fr.po b/debian/po/fr.po
deleted file mode 100644
index a96649d2fd..0000000000
--- a/debian/po/fr.po
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga 0.99.1-3\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2005-07-21 10:52+0200\n"
-"Last-Translator: Mohammed Adnène Trojette<adn+deb@diwi.org>\n"
-"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
-"Language: fr\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-15\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Faut-il vraiment arrêter le démon Quagga ?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"Veuillez noter que le démon de routage Quagga doit être arrêté avant de "
-"poursuivre cette installation. Cela peut provoquer des incohérences BGP ou "
-"des pertes de connectivité."
diff --git a/debian/po/it.po b/debian/po/it.po
deleted file mode 100644
index d305956685..0000000000
--- a/debian/po/it.po
+++ /dev/null
@@ -1,35 +0,0 @@
-# Italian translation of quagga debconf messages
-# Copyright (C) 2013, quagga package copyright holder
-# This file is distributed under the same license as the quagga package.
-# Beatrice Torracca <beatricet@libero.it>, 2013.
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2013-11-03 11:52+0200\n"
-"Last-Translator: Beatrice Torracca <beatricet@libero.it>\n"
-"Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n"
-"Language: it\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Virtaal 0.7.1\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Arrestare veramente il demone Quagga?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"ATTENZIONE: per procedere il demone di instradamento Quagga deve essere "
-"fermato. Questo può portare a flap BGP o a perdita della connettività di "
-"rete."
diff --git a/debian/po/ja.po b/debian/po/ja.po
deleted file mode 100644
index 0991d99236..0000000000
--- a/debian/po/ja.po
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2008 Christian Hammers <ch@debian.org>
-# This file is distributed under the same license as quagga package.
-# Hideki Yamane (Debian-JP) <henrich@debian.or.jp>, 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga 0.99.11-1\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2008-12-28 22:26+0900\n"
-"Last-Translator: Hideki Yamane (Debian-JP) <henrich@debian.or.jp>\n"
-"Language-Team: Japanese <debian-japanese@lists.debian.org>\n"
-"Language: ja\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Quagga デーモンを本当ã«åœæ­¢ã—ã¾ã™ã‹?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"警告: Quagga ルーティングデーモンã®åœæ­¢ãŒå®Ÿæ–½ã•れã¾ã—ãŸã€‚ã“れã«ã‚ˆã£ã¦ BGP "
-"ルートフラップã®ç™ºç”Ÿã‚„ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã®åˆ‡æ–­ãŒèµ·ã“ã•れるå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚"
diff --git a/debian/po/nl.po b/debian/po/nl.po
deleted file mode 100644
index a9df615e0c..0000000000
--- a/debian/po/nl.po
+++ /dev/null
@@ -1,35 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2007-03-15 18:49+0100\n"
-"Last-Translator: Bart Cornelis <cobaco@skolelinux.no>\n"
-"Language-Team: debian-l10n-dutch <debian-l10n-dutch@lists.debian.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Dutch\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Bent u zeker dat u de Quagga-achtergronddienst wilt stoppen?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"WAARSCHUWING: De Quagga 'routing'-achtergronddienst dient stopgezet te "
-"worden voor u verder gaat. Dit kan BGP-flaps en verliezen van "
-"netwerkverbinding veroorzaken."
diff --git a/debian/po/pt.po b/debian/po/pt.po
deleted file mode 100644
index 05f9b2e383..0000000000
--- a/debian/po/pt.po
+++ /dev/null
@@ -1,34 +0,0 @@
-# Portuguese translations for quagga package.
-# Copyright (C) 2007 Miguel Figueiredo
-# This file is distributed under the same license as the quagga package.
-# Miguel Figueiredo <elmig@debianpt.org>, 2007.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga 0.99.6-6\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2007-04-26 23:07+0100\n"
-"Last-Translator: Miguel Figueiredo <elmig@debianpt.org>\n"
-"Language-Team: Portuguese <traduz@debianpt.org>\n"
-"Language: pt\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Deseja mesmo parar o daemon Quagga?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"AVISO: O daemon de routing tem de ser parado para continuar. Isto pode levar "
-"a distúrbio do BGP ou perda da ligação de rede."
diff --git a/debian/po/pt_BR.po b/debian/po/pt_BR.po
deleted file mode 100644
index 49b399c3e7..0000000000
--- a/debian/po/pt_BR.po
+++ /dev/null
@@ -1,34 +0,0 @@
-# quagga Brazilian Portuguese po-debconf translation
-# Copyright (C) 2007 THE quagga'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the quagga package.
-# Jefferson Alexandre dos Santos <jefferson.alexandre@gmail.com>, 2007.
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2007-09-29 00:34-0300\n"
-"Last-Translator: Jefferson Alexandre dos Santos<jefferson.alexandre@gmail."
-"com>\n"
-"Language-Team: Brazilian Portuguese <debian-l10n-portuguese@lists.debian."
-"org>\n"
-"Language: pt_BR\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Você realmente deseja parar o daemon Quagga?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"AVISO: O daemon de roteamento Quagga precisa ser parado para prosseguir. "
-"Isto pode causar \"BGP flaps\" ou perda de conectividade de rede."
diff --git a/debian/po/ru.po b/debian/po/ru.po
deleted file mode 100644
index e1db9d37d3..0000000000
--- a/debian/po/ru.po
+++ /dev/null
@@ -1,37 +0,0 @@
-# translation of ru.po to Russian
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Yuri Kozlov <yuray@komyakino.ru>, 2009.
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga 0.99.13-1\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2009-07-19 09:04+0400\n"
-"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
-"Language-Team: Russian <debian-l10n-russian@lists.debian.org>\n"
-"Language: ru\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "ДейÑтвительно оÑтановить Ñлужбу Quagga?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"ПРЕДУПРЕЖДЕÐИЕ: Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñлужба маршрутизации Quagga должна "
-"быть оÑтановлена. Это может привеÑти к переÑтройке таблиц BGP или потере "
-"ÑвÑзноÑти узлов Ñети."
diff --git a/debian/po/sv.po b/debian/po/sv.po
deleted file mode 100644
index f97c5b8276..0000000000
--- a/debian/po/sv.po
+++ /dev/null
@@ -1,40 +0,0 @@
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-# Developers do not need to manually edit POT or PO files.
-# , fuzzy
-#
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: quagga 0.99.1-6\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: 2005-10-04 06:56+0200\n"
-"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
-"Language-Team: Swedish <sv@li.org>\n"
-"Language: sv\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-1\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr "Vill du stoppa Quagga-daemonen?"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
-"VARNING: routingdaemonen Quagga måste stoppas för att fortsätta. Detta kan "
-"leda till BGP-flaps eller att nätverksförbindelsen avbryts."
diff --git a/debian/po/templates.pot b/debian/po/templates.pot
deleted file mode 100644
index c6fb636872..0000000000
--- a/debian/po/templates.pot
+++ /dev/null
@@ -1,31 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: ch@debian.org\n"
-"POT-Creation-Date: 2006-07-15 20:31+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid "Do you really want to stop the Quagga daemon?"
-msgstr ""
-
-#. Type: boolean
-#. Description
-#: ../quagga.templates:1001
-msgid ""
-"WARNING: The Quagga routing daemon has to be stopped to proceed. This could "
-"lead to BGP flaps or loss of network connectivity."
-msgstr ""
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 5744505e64..0000000000
--- a/debian/rules
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/make -f
-
-export DH_VERBOSE=1
-export DEB_BUILD_HARDENING=1
-export DH_OPTIONS=-v
-
-ifeq ($(WANT_SNMP), 1)
- USE_SNMP=--enable-snmp
- $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience")
-else
- $(warning "DEBIAN: SNMP disabled, see README.Debian")
-endif
-
-ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
- DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-endif
-
-ifdef DEBIAN_JOBS
-MAKEFLAGS += -j$(DEBIAN_JOBS)
-endif
-
-%:
- dh $@ --with=systemd,autoreconf --parallel --dbg-package=frr-dbg --list-missing
-
-override_dh_auto_configure:
- # Frr needs /proc to check some BSD vs Linux specific stuff.
- # Else it fails with an obscure error message pointing out that
- # IPCTL_FORWARDING is an undefined symbol which is not very helpful.
- @if ! [ -d /proc/1 ]; then \
- echo "./configure needs a mounted /proc"; \
- exit 1; \
- fi
-
- if ! [ -e config.status ]; then \
- dh_auto_configure -- \
- --enable-exampledir=/usr/share/doc/frr/examples/ \
- --localstatedir=/var/run/frr \
- --sbindir=/usr/lib/frr \
- --sysconfdir=/etc/frr \
- $(USE_SNMP) \
- --enable-ospfapi=yes \
- --enable-vtysh=yes \
- --enable-isisd=yes \
- --enable-multipath=256 \
- --enable-user=frr \
- --enable-group=frr \
- --enable-vty-group=frrvty \
- --enable-configfile-mask=0640 \
- --enable-logfile-mask=0640 \
- --enable-werror \
- --enable-gcc-rdynamic \
- --with-libpam \
- --enable-systemd=yes \
- --enable-poll=yes \
- --enable-cumulus=yes \
- --enable-pimd=yes \
- --enable-dependency-tracking \
- --enable-bgp-vnc=no; \
- fi
-
-override_dh_auto_build:
- #dh_auto_build
- $(MAKE)
- dh_auto_build -- -C doc draft-zebra-00.txt
-
-
- # doc/ is a bit crazy
-ifeq ($(GENERATE_PDF), 1)
- dh_auto_build -- -C doc frr.pdf || true # pdfetex fails with exit code 1 but still produces a good looking .pdf
-endif
- rm -vf doc/frr.info
- dh_auto_build -- -C doc frr.info
- rm -vf doc/frr.info.html*
-
-override_dh_auto_test:
-
-override_dh_auto_install:
- dh_auto_install
-
- # cleaning up the info dir
- rm -f debian/tmp/usr/share/info/dir*
-
- # install config files
- mkdir -p debian/tmp/etc/frr/
- perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
-
- # installing the Frr specific SNMP MIB
-ifeq ($(WANT_SNMP), 1)
- install -D -m 644 ./zebra/GNOME-PRODUCT-ZEBRA-MIB debian/tmp/usr/share/snmp/mibs/GNOME-PRODUCT-ZEBRA-MIB
-else
- mkdir -p debian/tmp/usr/share/snmp/mibs/
-endif
-
- # cleaning .la files
- sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
-
-override_dh_systemd_start:
- dh_systemd_start frr.service
-
-override_dh_systemd_enable:
- dh_systemd_enable frr.service
-
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index 46ff1c7dab..0000000000
--- a/debian/watch
+++ /dev/null
@@ -1,8 +0,0 @@
-# Example watch control file for uscan
-# Rename this file to "watch" and then you can run the "uscan" command
-# to check for upstream updates and more.
-# Site Directory Pattern Version Script
-version=3
-opts=uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha|b|a)[\-\.]?\d*)$/$1~$2/ \
- http://download.savannah.gnu.org/releases/frr/quagga-(\d.*)\.(?:tgz|tar\.(?:gz|bz2|xz))
-# Bart Martens <bartm@debian.org> Fri, 25 Jan 2013 06:38:53 +0000
diff --git a/debianpkg/Makefile.am b/debianpkg/Makefile.am
new file mode 100644
index 0000000000..5ab5b4c4fc
--- /dev/null
+++ b/debianpkg/Makefile.am
@@ -0,0 +1,38 @@
+
+EXTRA_DIST = README.Debian README.Maintainer \
+ changelog compat control copyright \
+ rules source/format tests/control \
+ tests/daemons watchfrr.rc \
+ backports/README backports/rules \
+ backports/debian8/debian/source/format \
+ backports/debian8/exclude \
+ backports/debian8/versionext \
+ backports/debian9/debian/source/format \
+ backports/debian9/exclude \
+ backports/debian9/versionext \
+ backports/ubuntu12.04/debian/control \
+ backports/ubuntu12.04/debian/frr.install \
+ backports/ubuntu12.04/debian/frr.postinst \
+ backports/ubuntu12.04/debian/frr.postrm \
+ backports/ubuntu12.04/debian/rules \
+ backports/ubuntu12.04/debian/source/format \
+ backports/ubuntu12.04/exclude \
+ backports/ubuntu12.04/versionext \
+ backports/ubuntu14.04/debian/control \
+ backports/ubuntu14.04/debian/frr.install \
+ backports/ubuntu14.04/debian/frr.postinst \
+ backports/ubuntu14.04/debian/frr.postrm \
+ backports/ubuntu14.04/debian/rules \
+ backports/ubuntu14.04/debian/source/format \
+ backports/ubuntu14.04/exclude \
+ backports/ubuntu14.04/versionext \
+ backports/ubuntu16.04/debian/source/format \
+ backports/ubuntu16.04/exclude \
+ backports/ubuntu16.04/versionext \
+ frr-doc.docs frr-doc.info frr-doc.install \
+ frr-doc.lintian-overrides frr.conf \
+ frr.dirs frr.docs frr.install \
+ frr.lintian-overrides frr.logrotate \
+ frr.manpages frr.pam frr.postinst frr.postrm \
+ frr.preinst frr.prerm \
+ frr-pythontools.install
diff --git a/debian/README.Debian b/debianpkg/README.Debian
index 1b04803366..1b04803366 100644
--- a/debian/README.Debian
+++ b/debianpkg/README.Debian
diff --git a/debian/README.Maintainer b/debianpkg/README.Maintainer
index 84b68e1949..84b68e1949 100644
--- a/debian/README.Maintainer
+++ b/debianpkg/README.Maintainer
diff --git a/debianpkg/README.deb_build.md b/debianpkg/README.deb_build.md
new file mode 100644
index 0000000000..3156c3672d
--- /dev/null
+++ b/debianpkg/README.deb_build.md
@@ -0,0 +1,102 @@
+Building your own FRRouting Debian Package
+==========================================
+(Tested on Ubuntu 12.04, 14.04, 16.04 and Debian 8)
+
+1. Follow the package installation as outlined in doc/Building_on_XXXX.md
+ (XXXX refers your OS Distribution) to install the required build packages
+
+2. Install the following additional packages:
+
+ apt-get install realpath equivs groff fakeroot debhelper
+
+3. Checkout FRR under a **unpriviledged** user account
+
+ git clone https://github.com/frrouting/frr.git frr
+
+4. Run Bootstrap and make distribution tar.gz
+
+ cd frr
+ ./bootstrap.sh
+ ./configure --with-pkg-extra-version=-MyDebPkgVersion
+ make dist
+
+ Note: configure parameters are not important for the Debian Package
+ building - except the `with-pkg-extra-version` if you want to give the
+ Debian Package a specific name to mark your own unoffical build
+
+5. Edit `debianpkg/rules` and set the configuration as needed
+
+ Look for section `dh_auto_configure` to modify the configure
+ options as needed. Options might be different between main `rules` and
+ `backports/XXXX/debian/rules`. Please adjust as needed on all files
+
+6. Create backports debian sources
+
+ Move the `debianpkg` to `debian` and create the backports
+ (Debian requires to not ship a `debian` directory inside the source
+ directory to avoid build conflicts with the reserved `debian` subdirectory
+ name during the build)
+
+ mv debianpkg debian
+ make -f debian/rules backports
+
+ This will create a `frr_*.orig.tar.gz` with the source (same as dist tar),
+ and multiple `frr_*.debian.tar.xz` and `frr_*.dsc` for the debian package
+ source on each backport supported distribution
+
+6. Create a new directory to build the package and populate with package src
+
+ mkdir frrpkg
+ cd frrpkg
+ tar xf ~/frr/frr_*.orig.tar.gz
+ cd frr*
+ . /etc/os-release
+ tar xf ~/frr/frr_*${ID}${VERSION_ID}*.debian.tar.xz
+
+7. Build Debian Package Dependencies and install them as needed
+
+ sudo mk-build-deps --install debian/control
+
+8. Build Debian Package
+
+ debuild -b -uc -us
+
+DONE.
+
+If all works correctly, then you should end up with the Debian packages under
+`frrpkg`. If distributed, please make sure you distribute it together with
+the sources (`frr_*.orig.tar.gz`, `frr_*.debian.tar.xz` and `frr_*.dsc`)
+
+
+Enabling daemons after installation of the package:
+---------------------------------------------------
+
+1. Edit `/etc/frr/daemons` and enable required routing daemons (Zebra is
+probably needed for most deployments, so make sure to enable it.)
+
+2. Check your firewall / IPtables to make sure the routing protocols are
+allowed.
+
+3. Enable FRR at startup
+
+ - On `init.d` based systems (Ubuntu 12.04)
+
+ sudo update-rc.d frr defaults
+
+ - On `systemd` based systems (Debian 8, Ubuntu 14.04, 16.04)
+
+ sudo systemctl enable frr
+
+4. Start/Restart the daemons (or reboot)
+
+ - On `init.d` based systems (Ubuntu 12.04)
+
+ sudo invoke-rc.d frr start
+
+ - on `systemd` based systems (Debian 8, Ubuntu 14.04, 16.04)
+
+ sudo systemctl start frr
+
+
+Configuration is stored in `/etc/frr/*.conf` files and daemon selection
+is stored in `/etc/frr/daemons`.
diff --git a/debianpkg/backports/.gitignore b/debianpkg/backports/.gitignore
new file mode 100644
index 0000000000..3b20d26891
--- /dev/null
+++ b/debianpkg/backports/.gitignore
@@ -0,0 +1,2 @@
+*/*.dirhash
+*/debian/changelog
diff --git a/debianpkg/backports/README b/debianpkg/backports/README
new file mode 100644
index 0000000000..efd322e1d9
--- /dev/null
+++ b/debianpkg/backports/README
@@ -0,0 +1,28 @@
+This directory contains the debian directories for backports to other debian
+platforms. These are built via the `3.0 (custom)' source format, which
+allows one to build a source package directly out of tarballs (e.g. an
+orig.tar.gz tarball and a debian.tar.gz file), at which point the format can
+be changed to a real format (e.g. `3.0 (quilt)').
+
+Source packages are assembled via targets of the same name as the system to
+which the backport is done (e.g. `precise'), included in debian/rules.
+
+To create a new debian backport:
+
+* Add its name to `KNOWN_BACKPORTS', defined in debian/rules.
+* Create a directory of the same name in debian/backports.
+* Add the files `exclude', `versionext', and `debian/source/format' under
+ this directory:
+ * `exclude' contains whitespace-separated paths (relative to the root of
+ the source dir) that should be excluded from the source package (e.g.
+ debian/patches).
+ * `versionext' contains the suffix added to the version number for this
+ backport's build. Distributions often have guidelines for what this
+ should be. If left empty, no new debian/changelog entry is created.
+ * `debian/source/format' should contain the source format of the resulting
+ source package. As of of the writing of this document the only supported
+ format is `3.0 (quilt)'.
+* Add appropriate files under the `debian/' subdirectory. These will be
+ included in the source package, overriding any top-level `debian/' files
+ with equivalent paths.
+
diff --git a/debianpkg/backports/debian8/debian/source/format b/debianpkg/backports/debian8/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /dev/null
+++ b/debianpkg/backports/debian8/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debianpkg/backports/debian8/exclude b/debianpkg/backports/debian8/exclude
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/debianpkg/backports/debian8/exclude
diff --git a/debianpkg/backports/debian8/versionext b/debianpkg/backports/debian8/versionext
new file mode 100644
index 0000000000..4824521f8c
--- /dev/null
+++ b/debianpkg/backports/debian8/versionext
@@ -0,0 +1 @@
+-1~debian8+1
diff --git a/debianpkg/backports/debian9/debian/source/format b/debianpkg/backports/debian9/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /dev/null
+++ b/debianpkg/backports/debian9/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debianpkg/backports/debian9/exclude b/debianpkg/backports/debian9/exclude
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/debianpkg/backports/debian9/exclude
diff --git a/debianpkg/backports/debian9/versionext b/debianpkg/backports/debian9/versionext
new file mode 100644
index 0000000000..db85932115
--- /dev/null
+++ b/debianpkg/backports/debian9/versionext
@@ -0,0 +1 @@
+-1~debian9+1
diff --git a/debianpkg/backports/rules b/debianpkg/backports/rules
new file mode 100755
index 0000000000..d0c6dcc066
--- /dev/null
+++ b/debianpkg/backports/rules
@@ -0,0 +1,137 @@
+.PHONY: backports $(KNOWN_BACKPORTS)
+
+# error out if these files are missing
+required_files = $(foreach backport,$(KNOWN_BACKPORTS), \
+ $(addprefix debian/backports/$(backport)/, \
+ debian/source/format \
+ versionext \
+ exclude))
+$(if $(filter-out $(wildcard $(required_files)),$(required_files)), \
+ $(error missing required backports files: \
+ $(filter-out $(wildcard $(required_files)),$(required_files)). \
+ see debian/backports/README) \
+)
+
+TARBALLDIR ?= $(shell dh_testdir debian/changelog && realpath .)
+
+define backports-targets
+# if this file is empty, no automatic changelog entry is created
+VERSIONEXT_$(1) ?= $(strip \
+ $(shell cat $(wildcard debian/backports/$(1)/versionext)))
+DEBIAN_VERSION_$(1) = $(DEBIAN_VERSION)$$(VERSIONEXT_$(1))
+BACKPORTDIR_$(1) = $(realpath debian/backports/$(1))
+
+# as of right now, must be '3.0 (quilt)'
+SOURCEFORMAT_$(1) ?= $(strip \
+ $(shell cat debian/backports/$(1)/debian/source/format))
+
+# files checked for the dirhash (see below)
+FINDCMD_$(1) = find -L debian/backports/$(1)/debian \
+ -type f \
+ ! -path debian/backports/$(1)/debian/changelog
+
+# files *not* pulled from the root debian directory into the backport tarball:
+# debian/changelog (copied and edited for backport version entry)
+# debian/backports itself (relevant contents are copied out separately)
+# anything provided in the current backports debian dir
+# anything specified in the 'exclude' file in the current backports debian dir
+EXCLUDEROOT_$(1) = debian/changelog debian/backports \
+ $$(subst debian/backports/$(1)/,,$$(shell $$(FINDCMD_$(1)))) \
+ $$(shell cat debian/backports/$(1)/exclude)
+
+EXCLUDEROOT_TAR_$(1) = $$(foreach file,$$(EXCLUDEROOT_$(1)),--exclude $$(file))
+EXCLUDEROOT_FIND_$(1) = $$(foreach file,$$(EXCLUDEROOT_$(1)),-o -path $$(file))
+
+# find command resulting in all files that *will* be pulled into the backport
+# tarball.
+FINDCMDROOT_$(1) = find -L debian/ \
+ '(' -false $$(EXCLUDEROOT_FIND_$(1)) ')' -prune -o \
+ -type f -a '!' '(' -false $$(EXCLUDEROOT_FIND_$(1)) ')'
+
+# usually using `find' output for dependencies has the downfall of not tracking
+# file removal. Work around that by introducing a dependency on a file whose
+# name contains the hash of `find' output, so that the name will change when a
+# file is deleted.
+DIRHASH_$(1) = \
+ $$(shell $$(FINDCMD_$(1)) | sha1sum | sed -r 's/^(......).*/\1/')
+DIRHASHROOT_$(1) = \
+ $$(shell $$(FINDCMDROOT_$(1)) | sha1sum | sed -r 's/^(......).*/\1/')
+
+CONTROL_$(1) = $$(strip \
+ $$(if $$(wildcard $$(BACKPORTDIR_$(1))/debian/control), \
+ $$(BACKPORTDIR_$(1))/debian/control, \
+ $(realpath debian/control) \
+ ))
+
+# TARGETS:
+
+$(1): $(TARBALLDIR)/$(SRCPKG)_$$(DEBIAN_VERSION_$(1)).dsc ;
+
+# we use 3.0 (custom) to build a source package directly from tarballs,
+# bypassing the usual checks (which wouldn't like our combination-of-
+# directories approach)
+$(TARBALLDIR)/$(SRCPKG)_$$(DEBIAN_VERSION_$(1)).dsc:
+ dpkg-source -l$$(BACKPORTDIR_$(1))/debian/changelog \
+ -c$$(CONTROL_$(1)) \
+ --format='3.0 (custom)' \
+ --target-format='$$(SOURCEFORMAT_$(1))' \
+ -b . $$^
+ mv $(TARBALLDIR)/../$$(notdir $$@) $$@
+
+ifeq ($$(SOURCEFORMAT_$(1)),3.0 (quilt))
+# this target depends on the orig.tar.gz file, for which there is no target in
+# this makefile. It is assumed to either already exist or be built by a target
+# provided elsewhere in debian/rules (e.g. via pristine-tar)
+$$(if $$(findstring $(ORIG_VERSION),$$(DEBIAN_VERSION_$(1))), \
+ $$(info downstream version matches upstream version (good)), \
+ $$(error quilt format expects downstream version \
+ ($$(DEBIAN_VERSION_$(1))) to contain upstream version \
+ ($(ORIG_VERSION)). Make a new debian/changelog entry \
+ to reflect the new upstream release) \
+)
+
+$(TARBALLDIR)/$(SRCPKG)_$$(DEBIAN_VERSION_$(1)).dsc: \
+ $(TARBALLDIR)/$(SRCPKG)_$(ORIG_VERSION).orig.tar.gz \
+ $(TARBALLDIR)/$(SRCPKG)_$$(DEBIAN_VERSION_$(1)).debian.tar.xz
+else
+$$(error unsupported source format for $(1) backport: $$(SOURCEFORMAT_$(1)))
+endif #SOURCEFORMAT_$(1)
+
+# for 3.0 (quilt)
+$(TARBALLDIR)/$(SRCPKG)_$$(DEBIAN_VERSION_$(1)).debian.tar.xz: \
+ $$(BACKPORTDIR_$(1))/debian/changelog \
+ $$(shell $$(FINDCMD_$(1))) \
+ $$(BACKPORTDIR_$(1))/$$(DIRHASH_$(1)).backport.dirhash \
+ $$(shell $$(FINDCMDROOT_$(1))) \
+ $$(BACKPORTDIR_$(1))/$$(DIRHASHROOT_$(1)).root.dirhash \
+ $$(BACKPORTDIR_$(1))/exclude
+ rm -f $$(subst .tar.xz,.tar,$$@) $$@
+ tar -chf $$(subst .tar.xz,.tar,$$@) \
+ --exclude-vcs $$(EXCLUDEROOT_TAR_$(1)) debian/
+ cd debian/backports/$(1) && tar -uhf $$(subst .tar.xz,.tar,$$@) \
+ --exclude-vcs debian/
+ xz $$(subst .tar.xz,.tar,$$@)
+
+$$(BACKPORTDIR_$(1))/debian/changelog: \
+ debian/changelog \
+ debian/backports/$(1)/versionext
+ rm -f debian/backports/$(1)/debian/changelog
+ cp $$< $$@
+ $(if $$(VERSIONEXT_$(1)), \
+ dch -c $$@ -v '$$(DEBIAN_VERSION_$(1))' -b \
+ 'backport to $(1) systems', \
+ )
+
+$$(BACKPORTDIR_$(1))/$$(DIRHASH_$(1)).backport.dirhash:
+ rm -f debian/backports/$(1)/*.backport.dirhash
+ touch $$@
+
+$$(BACKPORTDIR_$(1))/$$(DIRHASHROOT_$(1)).root.dirhash:
+ rm -f debian/backports/$(1)/*.root.dirhash
+ touch $$@
+
+endef # backports-targets
+$(foreach backport,$(KNOWN_BACKPORTS),$(eval \
+ $(call backports-targets,$(backport))))
+
+backports: $(KNOWN_BACKPORTS)
diff --git a/debianpkg/backports/ubuntu12.04/debian/control b/debianpkg/backports/ubuntu12.04/debian/control
new file mode 100644
index 0000000000..17ceeb0381
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/debian/control
@@ -0,0 +1,56 @@
+Source: frr
+Section: net
+Priority: optional
+Maintainer: Nobody <nobody@frrouting.org>
+Uploaders: Nobody <nobody@frrouting.org>
+XSBC-Original-Maintainer: <maintainers@frrouting.org>
+Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, pkg-config, python (>= 2.7), python-ipaddr
+Standards-Version: 3.9.6
+Homepage: http://www.frrouting.org/
+XS-Testsuite: autopkgtest
+
+Package: frr
+Architecture: any
+Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends}
+Pre-Depends: adduser
+Conflicts: zebra, zebra-pj
+Replaces: zebra, zebra-pj
+Suggests: snmpd
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga
+ FRR is free software which manages TCP/IP based routing protocols.
+ It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, RIPng,
+ PIM and LDP as well as the IPv6 versions of these.
+ .
+ FRR is a fork of Quagga with an open community model. The main git
+ lives on https://github.com/frrouting/frr.git
+
+Package: frr-dbg
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version})
+Priority: extra
+Section: debug
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (debug symbols)
+ This package provides debugging symbols for all binary packages built
+ from frr source package. It's highly recommended to have this package
+ installed before reporting any FRR crashes to either FRR developers or
+ Debian package maintainers.
+
+Package: frr-doc
+Section: net
+Architecture: all
+Depends: ${misc:Depends}
+Suggests: frr
+Description: documentation files for FRR
+ This package includes info files for frr, a free software which manages
+ TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
+ IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
+
+Package: frr-pythontools
+Section: net
+Architecture: all
+Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools)
+ This package includes info files for frr, a free software which manages
+ TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
+ IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
+
diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.install b/debianpkg/backports/ubuntu12.04/debian/frr.install
new file mode 120000
index 0000000000..83ecca5958
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/debian/frr.install
@@ -0,0 +1 @@
+../../ubuntu14.04/debian/frr.install \ No newline at end of file
diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postinst b/debianpkg/backports/ubuntu12.04/debian/frr.postinst
new file mode 120000
index 0000000000..eb98053c7b
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/debian/frr.postinst
@@ -0,0 +1 @@
+../../ubuntu14.04/debian/frr.postinst \ No newline at end of file
diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postrm b/debianpkg/backports/ubuntu12.04/debian/frr.postrm
new file mode 120000
index 0000000000..4f4380872f
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/debian/frr.postrm
@@ -0,0 +1 @@
+../../ubuntu14.04/debian/frr.postrm \ No newline at end of file
diff --git a/debianpkg/backports/ubuntu12.04/debian/rules b/debianpkg/backports/ubuntu12.04/debian/rules
new file mode 100755
index 0000000000..5c3e1363ce
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/debian/rules
@@ -0,0 +1,179 @@
+#!/usr/bin/make -f
+
+# FRRouting Configuration options
+######################################
+#
+# WANT_xxxx --> Set to 1 for enable, 0 for disable
+# The following are the defaults. They can be overridden by setting a
+# env variable to a different value
+#
+# export WANT_LDP=1
+# export WANT_PIM=1
+# export WANT_OSPFAPI=1
+# export WANT_TCP_ZEBRA=0
+# export WANT_BGP_VNC=0
+# export WANT_CUMULUS_MODE=0
+# export WANT_MULTIPATH=1
+#
+# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
+# Please be aware that 0 is NOT disabled, but treated as unlimited
+# export MULTIPATH=256
+#
+# Set the following to the value required (or leave undefined for the default below)
+# WANT_FRR_USER is used for the username and groupname of the FRR user account
+# export WANT_FRR_USER=frr
+# export WANT_FRR_VTY_GROUP=frrvty
+#
+####################################
+
+export DH_VERBOSE=1
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+export DH_OPTIONS=-v
+
+ifeq ($(WANT_SNMP), 1)
+ USE_SNMP=--enable-snmp
+ $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience")
+else
+ $(warning "DEBIAN: SNMP disabled, see README.Debian")
+endif
+
+ifneq ($(WANT_LDP), 0)
+ USE_LDP=--enable-ldpd
+else
+ USE_LDP=--disable-ldpd
+endif
+
+ifneq ($(WANT_PIM), 0)
+ USE_PIM=--enable-pimd
+else
+ USE_PIM=--disable-pimd
+endif
+
+ifneq ($(WANT_OSPFAPI), 0)
+ USE_OSPFAPI=--enable-ospfapi=yes
+else
+ USE_OSPFAPI=--enable-ospfapi=no
+endif
+
+ifeq ($(WANT_TCP_ZEBRA),1)
+ USE_TCP_ZEBRA=--enable-tcp-zebra
+endif
+
+ifneq ($(WANT_BGP_VNC), 0)
+ USE_BGP_VNC=--enable-bgp-vnc=yes
+else
+ USE_BGP_VNC=--enable-bgp-vnc=no
+endif
+
+ifndef WANT_FRR_USER
+ USE_FRR_USER=--enable-user=frr
+ USE_FRR_GROUP=--enable-group=frr
+else
+ USE_FRR_USER=$(WANT_FRR_USER)
+ USE_FRR_GROUP=$(WANT_FRR_USER)
+endif
+
+ifndef WANT_FRR_VTY_GROUP
+ USE_FRR_VTY_GROUP=--enable-vty-group=frrvty
+else
+ USE_FRR_VTY_GROUP=--enable-vty-group=$(WANT_FRR_VTY_GROUP)
+endif
+
+ifneq ($(WANT_MULTIPATH), 0)
+ ifdef MULTIPATH
+ USE_MULTIPATH=--enable-multipath=$(MULTIPATH)
+ else
+ USE_MULTIPATH=--enable-multipath=256
+ endif
+else
+ USE_MULTIPATH=--disable-multipath
+endif
+
+ifeq ($(WANT_CUMULUS_NODE), 1)
+ USE_CUMULUS=--enable-cumulus=yes
+else
+ USE_CUMULUS=--enable-cumulus=no
+endif
+
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+ DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+endif
+
+ifdef DEBIAN_JOBS
+MAKEFLAGS += -j$(DEBIAN_JOBS)
+endif
+
+%:
+ dh $@ --with=autoreconf --parallel --dbg-package=frr-dbg --list-missing
+
+override_dh_auto_configure:
+ # Frr needs /proc to check some BSD vs Linux specific stuff.
+ # Else it fails with an obscure error message pointing out that
+ # IPCTL_FORWARDING is an undefined symbol which is not very helpful.
+ @if ! [ -d /proc/1 ]; then \
+ echo "./configure needs a mounted /proc"; \
+ exit 1; \
+ fi
+
+ if ! [ -e config.status ]; then \
+ dh_auto_configure -- \
+ --enable-exampledir=/usr/share/doc/frr/examples/ \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ $(USE_SNMP) \
+ $(USE_OSPFAPI) \
+ $(USE_MULTIPATH) \
+ $(USE_LDP) \
+ $(USE_TCP_ZEBRA) \
+ --enable-fpm \
+ $(USE_FRR_USER) $(USE_FRR_GROUP) \
+ $(USE_FRR_VTY_GROUP) \
+ --enable-configfile-mask=0640 \
+ --enable-logfile-mask=0640 \
+ --with-libpam \
+ --enable-systemd=no \
+ --enable-poll=yes \
+ $(USE_CUMULUS) \
+ $(USE_PIM) \
+ --enable-dependency-tracking \
+ $(USE_BGP_VNC) \
+ $(shell dpkg-buildflags --export=configure); \
+ fi
+
+override_dh_auto_build:
+ #dh_auto_build
+ $(MAKE)
+ dh_auto_build -- -C doc draft-zebra-00.txt
+
+
+ # doc/ is a bit crazy
+ifeq ($(GENERATE_PDF), 1)
+ dh_auto_build -- -C doc frr.pdf || true # pdfetex fails with exit code 1 but still produces a good looking .pdf
+endif
+ rm -vf doc/frr.info
+ dh_auto_build -- -C doc frr.info
+ rm -vf doc/frr.info.html*
+
+override_dh_auto_test:
+
+override_dh_auto_install:
+ dh_auto_install
+
+ # installed in frr-pythontools
+ rm debian/tmp/usr/lib/frr/frr-reload.py
+
+ # cleaning up the info dir
+ rm -f debian/tmp/usr/share/info/dir*
+
+ # install config files
+ mkdir -p debian/tmp/etc/frr/
+ perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
+
+ # installing the Frr specific SNMP MIB
+ install -D -m 644 ./zebra/GNOME-PRODUCT-ZEBRA-MIB debian/tmp/usr/share/snmp/mibs/GNOME-PRODUCT-ZEBRA-MIB
+
+ # cleaning .la files
+ sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
+ sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la
+
diff --git a/debianpkg/backports/ubuntu12.04/debian/source/format b/debianpkg/backports/ubuntu12.04/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debianpkg/backports/ubuntu12.04/exclude b/debianpkg/backports/ubuntu12.04/exclude
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/exclude
diff --git a/debianpkg/backports/ubuntu12.04/versionext b/debianpkg/backports/ubuntu12.04/versionext
new file mode 100644
index 0000000000..159e2e4160
--- /dev/null
+++ b/debianpkg/backports/ubuntu12.04/versionext
@@ -0,0 +1 @@
+-1~ubuntu12.04+1
diff --git a/debianpkg/backports/ubuntu14.04/debian/control b/debianpkg/backports/ubuntu14.04/debian/control
new file mode 100644
index 0000000000..c22bd3bd58
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/debian/control
@@ -0,0 +1,56 @@
+Source: frr
+Section: net
+Priority: optional
+Maintainer: Nobody <nobody@frrouting.org>
+Uploaders: Nobody <nobody@frrouting.org>
+XSBC-Original-Maintainer: <maintainers@frrouting.org>
+Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2, pkg-config, python (>= 2.7), python-ipaddr
+Standards-Version: 3.9.6
+Homepage: http://www.frrouting.org/
+XS-Testsuite: autopkgtest
+
+Package: frr
+Architecture: any
+Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends}
+Pre-Depends: adduser
+Conflicts: zebra, zebra-pj
+Replaces: zebra, zebra-pj
+Suggests: snmpd
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga
+ FRR is free software which manages TCP/IP based routing protocols.
+ It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, RIPng,
+ PIM and LDP as well as the IPv6 versions of these.
+ .
+ FRR is a fork of Quagga with an open community model. The main git
+ lives on https://github.com/frrouting/frr.git
+
+Package: frr-dbg
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version})
+Priority: extra
+Section: debug
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (debug symbols)
+ This package provides debugging symbols for all binary packages built
+ from frr source package. It's highly recommended to have this package
+ installed before reporting any FRR crashes to either FRR developers or
+ Debian package maintainers.
+
+Package: frr-doc
+Section: net
+Architecture: all
+Depends: ${misc:Depends}
+Suggests: frr
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (documentation)
+ This package includes info files for frr, a free software which manages
+ TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
+ IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
+
+Package: frr-pythontools
+Section: net
+Architecture: all
+Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools)
+ This package includes info files for frr, a free software which manages
+ TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
+ IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
+
diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.install b/debianpkg/backports/ubuntu14.04/debian/frr.install
new file mode 100644
index 0000000000..adce915e1f
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/debian/frr.install
@@ -0,0 +1,21 @@
+etc/frr/
+usr/bin/vtysh
+usr/include/frr/
+usr/lib/
+tools/frr etc/init.d/
+usr/share/doc/frr/
+usr/share/man/man1/vtysh.1
+usr/share/man/man1/frr.1
+usr/share/man/man8
+usr/share/man/man8/bgpd.8
+usr/share/man/man8/ospf6d.8
+usr/share/man/man8/ospfd.8
+usr/share/man/man8/ripd.8
+usr/share/man/man8/ripngd.8
+usr/share/man/man8/zebra.8
+usr/share/man/man8/isisd.8
+usr/share/man/man8/watchfrr.8
+usr/share/snmp/mibs/
+tools/etc/* etc/
+tools/*.service lib/systemd/system
+debian/frr.conf usr/lib/tmpfiles.d
diff --git a/debian/frr.postinst b/debianpkg/backports/ubuntu14.04/debian/frr.postinst
index 9020d7bf7a..b1d463a33d 100644
--- a/debian/frr.postinst
+++ b/debianpkg/backports/ubuntu14.04/debian/frr.postinst
@@ -32,9 +32,7 @@ if [ "$1" = "abort-upgrade" ]; then
exit 0
fi
-. /usr/share/debconf/confmodule
-
-db_stop
+update-rc.d frr defaults > /dev/null
#DEBHELPER#
diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postrm b/debianpkg/backports/ubuntu14.04/debian/frr.postrm
new file mode 100644
index 0000000000..48c23321f7
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/debian/frr.postrm
@@ -0,0 +1,14 @@
+#!/bin/bash -e
+
+if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
+${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"}
+# set -u not because of debhelper
+
+update-rc.d -f frr remove >> /dev/null
+
+if [ "$1" = "purge" ]; then
+ rm -rf /etc/frr /var/run/frr /var/log/frr
+ userdel frr >/dev/null 2>&1 || true
+fi
+
+#DEBHELPER#
diff --git a/debianpkg/backports/ubuntu14.04/debian/rules b/debianpkg/backports/ubuntu14.04/debian/rules
new file mode 100755
index 0000000000..b1f539def6
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/debian/rules
@@ -0,0 +1,185 @@
+#!/usr/bin/make -f
+
+# FRRouting Configuration options
+######################################
+#
+# WANT_xxxx --> Set to 1 for enable, 0 for disable
+# The following are the defaults. They can be overridden by setting a
+# env variable to a different value
+#
+# export WANT_LDP=1
+# export WANT_PIM=1
+# export WANT_OSPFAPI=1
+# export WANT_TCP_ZEBRA=0
+# export WANT_BGP_VNC=0
+# export WANT_CUMULUS_MODE=0
+# export WANT_MULTIPATH=1
+#
+# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
+# Please be aware that 0 is NOT disabled, but treated as unlimited
+# export MULTIPATH=256
+#
+# Set the following to the value required (or leave undefined for the default below)
+# WANT_FRR_USER is used for the username and groupname of the FRR user account
+# export WANT_FRR_USER=frr
+# export WANT_FRR_VTY_GROUP=frrvty
+#
+####################################
+
+export DH_VERBOSE=1
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+export DH_OPTIONS=-v
+
+ifeq ($(WANT_SNMP), 1)
+ USE_SNMP=--enable-snmp
+ $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience")
+else
+ $(warning "DEBIAN: SNMP disabled, see README.Debian")
+endif
+
+ifneq ($(WANT_LDP), 0)
+ USE_LDP=--enable-ldpd
+else
+ USE_LDP=--disable-ldpd
+endif
+
+ifneq ($(WANT_PIM), 0)
+ USE_PIM=--enable-pimd
+else
+ USE_PIM=--disable-pimd
+endif
+
+ifneq ($(WANT_OSPFAPI), 0)
+ USE_OSPFAPI=--enable-ospfapi=yes
+else
+ USE_OSPFAPI=--enable-ospfapi=no
+endif
+
+ifeq ($(WANT_TCP_ZEBRA),1)
+ USE_TCP_ZEBRA=--enable-tcp-zebra
+endif
+
+ifneq ($(WANT_BGP_VNC), 0)
+ USE_BGP_VNC=--enable-bgp-vnc=yes
+else
+ USE_BGP_VNC=--enable-bgp-vnc=no
+endif
+
+ifndef WANT_FRR_USER
+ USE_FRR_USER=--enable-user=frr
+ USE_FRR_GROUP=--enable-group=frr
+else
+ USE_FRR_USER=$(WANT_FRR_USER)
+ USE_FRR_GROUP=$(WANT_FRR_USER)
+endif
+
+ifndef WANT_FRR_VTY_GROUP
+ USE_FRR_VTY_GROUP=--enable-vty-group=frrvty
+else
+ USE_FRR_VTY_GROUP=--enable-vty-group=$(WANT_FRR_VTY_GROUP)
+endif
+
+ifneq ($(WANT_MULTIPATH), 0)
+ ifdef MULTIPATH
+ USE_MULTIPATH=--enable-multipath=$(MULTIPATH)
+ else
+ USE_MULTIPATH=--enable-multipath=256
+ endif
+else
+ USE_MULTIPATH=--disable-multipath
+endif
+
+ifeq ($(WANT_CUMULUS_NODE), 1)
+ USE_CUMULUS=--enable-cumulus=yes
+else
+ USE_CUMULUS=--enable-cumulus=no
+endif
+
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+ DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+endif
+
+ifdef DEBIAN_JOBS
+MAKEFLAGS += -j$(DEBIAN_JOBS)
+endif
+
+%:
+ dh $@ --with=autoreconf --parallel --dbg-package=frr-dbg --list-missing
+
+override_dh_auto_configure:
+ # Frr needs /proc to check some BSD vs Linux specific stuff.
+ # Else it fails with an obscure error message pointing out that
+ # IPCTL_FORWARDING is an undefined symbol which is not very helpful.
+ @if ! [ -d /proc/1 ]; then \
+ echo "./configure needs a mounted /proc"; \
+ exit 1; \
+ fi
+
+ if ! [ -e config.status ]; then \
+ dh_auto_configure -- \
+ --enable-exampledir=/usr/share/doc/frr/examples/ \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ $(USE_SNMP) \
+ $(USE_OSPFAPI) \
+ $(USE_MULTIPATH) \
+ $(USE_LDP) \
+ $(USE_TCP_ZEBRA) \
+ --enable-fpm \
+ $(USE_FRR_USER) $(USE_FRR_GROUP) \
+ $(USE_FRR_VTY_GROUP) \
+ --enable-configfile-mask=0640 \
+ --enable-logfile-mask=0640 \
+ --with-libpam \
+ --enable-systemd=no \
+ --enable-poll=yes \
+ $(USE_CUMULUS) \
+ $(USE_PIM) \
+ --enable-dependency-tracking \
+ $(USE_BGP_VNC) \
+ $(shell dpkg-buildflags --export=configure); \
+ fi
+
+override_dh_auto_build:
+ #dh_auto_build
+ $(MAKE)
+ dh_auto_build -- -C doc draft-zebra-00.txt
+
+
+ # doc/ is a bit crazy
+ifeq ($(GENERATE_PDF), 1)
+ dh_auto_build -- -C doc frr.pdf || true # pdfetex fails with exit code 1 but still produces a good looking .pdf
+endif
+ rm -vf doc/frr.info
+ dh_auto_build -- -C doc frr.info
+ rm -vf doc/frr.info.html*
+
+override_dh_auto_test:
+
+override_dh_auto_install:
+ dh_auto_install
+
+ # installed in frr-pythontools
+ rm debian/tmp/usr/lib/frr/frr-reload.py
+
+ # cleaning up the info dir
+ rm -f debian/tmp/usr/share/info/dir*
+
+ # install config files
+ mkdir -p debian/tmp/etc/frr/
+ perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
+
+ # installing the Frr specific SNMP MIB
+ install -D -m 644 ./zebra/GNOME-PRODUCT-ZEBRA-MIB debian/tmp/usr/share/snmp/mibs/GNOME-PRODUCT-ZEBRA-MIB
+
+ # cleaning .la files
+ sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
+ sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la
+
+override_dh_systemd_start:
+ dh_systemd_start frr.service
+
+override_dh_systemd_enable:
+ dh_systemd_enable frr.service
+
diff --git a/debianpkg/backports/ubuntu14.04/debian/source/format b/debianpkg/backports/ubuntu14.04/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debianpkg/backports/ubuntu14.04/exclude b/debianpkg/backports/ubuntu14.04/exclude
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/exclude
diff --git a/debianpkg/backports/ubuntu14.04/versionext b/debianpkg/backports/ubuntu14.04/versionext
new file mode 100644
index 0000000000..c5be0650af
--- /dev/null
+++ b/debianpkg/backports/ubuntu14.04/versionext
@@ -0,0 +1 @@
+-1~ubuntu14.04+1
diff --git a/debianpkg/backports/ubuntu16.04/debian/source/format b/debianpkg/backports/ubuntu16.04/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /dev/null
+++ b/debianpkg/backports/ubuntu16.04/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debianpkg/backports/ubuntu16.04/exclude b/debianpkg/backports/ubuntu16.04/exclude
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/debianpkg/backports/ubuntu16.04/exclude
diff --git a/debianpkg/backports/ubuntu16.04/versionext b/debianpkg/backports/ubuntu16.04/versionext
new file mode 100644
index 0000000000..dc33d97a12
--- /dev/null
+++ b/debianpkg/backports/ubuntu16.04/versionext
@@ -0,0 +1 @@
+-1~ubuntu16.04+1
diff --git a/debian/changelog b/debianpkg/changelog.in
index 4ea86929fc..8f3f4753de 100644
--- a/debian/changelog
+++ b/debianpkg/changelog.in
@@ -1,10 +1,16 @@
-frr (3.1-dev) Released; urgency=medium
+frr (@VERSION@) RELEASED; urgency=medium
* New Enabled: PIM draft Unnumbered
- -- frr <frog@lists.frrouting.org> Wed, 5 Apr 2017 22:29:42 -0500
+ -- FRRouting-Dev <dev@lists.frrouting.org> Wed, 18 Oct 2017 17:01:42 -0700
-frr (3.0) Released; urgency=medium
+frr (3.0-1) RELEASED; urgency=medium
+
+ * Added Debian 9 Backport
+
+ -- FRRouting-Dev <dev@lists.frrouting.org> Mon, 16 Oct 2017 03:28:00 -0700
+
+frr (3.0-0) RELEASED; urgency=medium
* New Enabled: BGP Shutdown Message
* New Enabled: BGP Large Community
@@ -22,14 +28,15 @@ frr (3.0) Released; urgency=medium
* New Enabled: PIM Sparse Mode
* New Enabled: NHRP RFC 2332
* New Enabled: Label Manager
+ * Switched from hardening-wrapper to dpkg-buildflags.
- -- frr <frr@lists.nox.tf> Wed, 5 Apr 2017 22:23:42 -0500
+ -- FRRouting-Dev <dev@lists.frrouting.org> Fri, 13 Oct 2017 16:17:26 -0700
-frr (2.1) Released; urgency=medium
+frr (2.0-0) RELEASED; urgency=medium
* Switchover to FRR
- -- frr <frr@lists.nox.tf> Mon, 23 Jan 2017 16:30:22 -0400
+ -- FRRouting-Dev <dev@lists.frrouting.org> Mon, 23 Jan 2017 16:30:22 -0400
quagga (0.99.24+cl3u5) RELEASED; urgency=medium
diff --git a/debian/compat b/debianpkg/compat
index 7f8f011eb7..7f8f011eb7 100644
--- a/debian/compat
+++ b/debianpkg/compat
diff --git a/debianpkg/control b/debianpkg/control
new file mode 100644
index 0000000000..297a7cf106
--- /dev/null
+++ b/debianpkg/control
@@ -0,0 +1,54 @@
+Source: frr
+Section: net
+Priority: optional
+Maintainer: Nobody <nobody@frrouting.org>
+Uploaders: Nobody <nobody@frrouting.org>
+XSBC-Original-Maintainer: <maintainers@frrouting.org>
+Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr
+Standards-Version: 3.9.6
+Homepage: http://www.frrouting.org/
+
+Package: frr
+Architecture: any
+Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute2 | iproute, ${misc:Depends}, libc-ares2
+Pre-Depends: adduser
+Conflicts: zebra, zebra-pj, quagga
+Replaces: zebra, zebra-pj
+Suggests: snmpd
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga
+ FRR is free software which manages TCP/IP based routing protocols.
+ It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, RIPng,
+ PIM and LDP as well as the IPv6 versions of these.
+ .
+ FRR is a fork of Quagga with an open community model. The main git
+ lives on https://github.com/frrouting/frr.git
+
+Package: frr-dbg
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version})
+Priority: extra
+Section: debug
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (debug symbols)
+ This package provides debugging symbols for all binary packages built
+ from frr source package. It's highly recommended to have this package
+ installed before reporting any FRR crashes to either FRR developers or
+ Debian package maintainers.
+
+Package: frr-doc
+Section: net
+Architecture: all
+Depends: ${misc:Depends}
+Suggests: frr
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (documentation)
+ This package includes info files for frr, a free software which manages
+ TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
+ IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
+
+Package: frr-pythontools
+Section: net
+Architecture: all
+Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr
+Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools)
+ This package includes info files for frr, a free software which manages
+ TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
+ IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
diff --git a/debian/copyright b/debianpkg/copyright
index 7b873abd31..7b873abd31 100644
--- a/debian/copyright
+++ b/debianpkg/copyright
diff --git a/debian/frr-doc.docs b/debianpkg/frr-doc.docs
index a0776fd68a..a0776fd68a 100644
--- a/debian/frr-doc.docs
+++ b/debianpkg/frr-doc.docs
diff --git a/debian/frr-doc.info b/debianpkg/frr-doc.info
index c4f181cdb0..c4f181cdb0 100644
--- a/debian/frr-doc.info
+++ b/debianpkg/frr-doc.info
diff --git a/debianpkg/frr-doc.install b/debianpkg/frr-doc.install
new file mode 100644
index 0000000000..e5910fec8f
--- /dev/null
+++ b/debianpkg/frr-doc.install
@@ -0,0 +1,2 @@
+usr/share/info
+doc/*.png usr/share/info
diff --git a/debian/frr-doc.lintian-overrides b/debianpkg/frr-doc.lintian-overrides
index 1fe64ffd53..1fe64ffd53 100644
--- a/debian/frr-doc.lintian-overrides
+++ b/debianpkg/frr-doc.lintian-overrides
diff --git a/debianpkg/frr-pythontools.install b/debianpkg/frr-pythontools.install
new file mode 100644
index 0000000000..aee093cf69
--- /dev/null
+++ b/debianpkg/frr-pythontools.install
@@ -0,0 +1 @@
+tools/frr-reload.py usr/lib/frr/
diff --git a/debian/frr.conf b/debianpkg/frr.conf
index dee3cd849a..dee3cd849a 100644
--- a/debian/frr.conf
+++ b/debianpkg/frr.conf
diff --git a/debian/frr.dirs b/debianpkg/frr.dirs
index 56699b2daa..56699b2daa 100644
--- a/debian/frr.dirs
+++ b/debianpkg/frr.dirs
diff --git a/debian/frr.docs b/debianpkg/frr.docs
index f72aae1967..f72aae1967 100644
--- a/debian/frr.docs
+++ b/debianpkg/frr.docs
diff --git a/debian/frr.install b/debianpkg/frr.install
index 8fc5fa5fa6..2d86009dba 100644
--- a/debian/frr.install
+++ b/debianpkg/frr.install
@@ -2,7 +2,6 @@ etc/frr/
usr/bin/vtysh
usr/include/frr/
usr/lib/
-tools/frr-reload.py usr/lib/frr/
tools/frr usr/lib/frr
usr/share/doc/frr/
usr/share/man/man1/vtysh.1
diff --git a/debian/frr.lintian-overrides b/debianpkg/frr.lintian-overrides
index e21bd9256d..e352ad6cf4 100644
--- a/debian/frr.lintian-overrides
+++ b/debianpkg/frr.lintian-overrides
@@ -1,3 +1,4 @@
frr: non-dev-pkg-with-shlib-symlink usr/lib/libfrrospfapiclient.so.0.0.0 usr/lib/libfrrospfapiclient.so
frr: non-dev-pkg-with-shlib-symlink usr/lib/libfrr.so.0.0.0 usr/lib/libfrr.so
-frr: package-name-doesnt-match-sonames libfrrospf0 libfrrospfapiclient0 libfrr0
+frr: non-dev-pkg-with-shlib-symlink usr/lib/libfrrfpm_pb.so.0.0.0 usr/lib/libfrrfpm_pb.so
+frr: package-name-doesnt-match-sonames libfrr0 libfrrfpm-pb0 libfrrospfapiclient0
diff --git a/debian/frr.logrotate b/debianpkg/frr.logrotate
index 2b4acd89c7..2b4acd89c7 100644
--- a/debian/frr.logrotate
+++ b/debianpkg/frr.logrotate
diff --git a/debian/frr.manpages b/debianpkg/frr.manpages
index 17a128b7e3..17a128b7e3 100644
--- a/debian/frr.manpages
+++ b/debianpkg/frr.manpages
diff --git a/debian/frr.pam b/debianpkg/frr.pam
index 2b106d43bc..2b106d43bc 100644
--- a/debian/frr.pam
+++ b/debianpkg/frr.pam
diff --git a/debianpkg/frr.postinst b/debianpkg/frr.postinst
new file mode 100644
index 0000000000..cbc45f03eb
--- /dev/null
+++ b/debianpkg/frr.postinst
@@ -0,0 +1,36 @@
+#!/bin/bash -e
+
+######################
+PASSWDFILE=/etc/passwd
+GROUPFILE=/etc/group
+
+frruid=`egrep "^frr:" $PASSWDFILE | awk -F ":" '{ print $3 }'`
+frrgid=`egrep "^frr:" $GROUPFILE | awk -F ":" '{ print $3 }'`
+frrvtygid=`egrep "^frrvty:" $GROUPFILE | awk -F ":" '{ print $3 }'`
+
+[ -n ${frruid} ] || (echo "No uid for frr in ${PASSWDFILE}" && /bin/false)
+[ -n ${frrgid} ] || (echo "No gid for frr in ${GROUPFILE}" && /bin/false)
+[ -n ${frrVTYgid} ] || (echo "No gid for frrvty in ${GROUPFILE}" && /bin/false)
+
+chown -R ${frruid}:${frrgid} /etc/frr
+touch /etc/frr/vtysh.conf
+chgrp ${frrvtygid} /etc/frr/vtysh*
+chmod 644 /etc/frr/*
+
+ENVIRONMENTFILE=/etc/environment
+if ! grep --quiet VTYSH_PAGER=/bin/cat ${ENVIRONMENTFILE}; then
+ echo "VTYSH_PAGER=/bin/cat" >> ${ENVIRONMENTFILE}
+fi
+##################################################
+
+if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
+${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"}
+
+# This is most likely due to the answer "no" to the "really stop the server"
+# question in the prerm script.
+if [ "$1" = "abort-upgrade" ]; then
+ exit 0
+fi
+
+#DEBHELPER#
+
diff --git a/debian/frr.postrm b/debianpkg/frr.postrm
index 26576fd136..26576fd136 100644
--- a/debian/frr.postrm
+++ b/debianpkg/frr.postrm
diff --git a/debian/frr.preinst b/debianpkg/frr.preinst
index 29162e3b56..29162e3b56 100644
--- a/debian/frr.preinst
+++ b/debianpkg/frr.preinst
diff --git a/debian/frr.prerm b/debianpkg/frr.prerm
index e0df24e10f..4b71202810 100644
--- a/debian/frr.prerm
+++ b/debianpkg/frr.prerm
@@ -1,7 +1,5 @@
#!/bin/bash -e
-. /usr/share/debconf/confmodule
-
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"}
diff --git a/debianpkg/rules b/debianpkg/rules
new file mode 100755
index 0000000000..04d28762aa
--- /dev/null
+++ b/debianpkg/rules
@@ -0,0 +1,218 @@
+#!/usr/bin/make -f
+
+# FRRouting Configuration options
+######################################
+#
+# WANT_xxxx --> Set to 1 for enable, 0 for disable
+# The following are the defaults. They can be overridden by setting a
+# env variable to a different value
+#
+# export WANT_LDP=1
+# export WANT_PIM=1
+# export WANT_OSPFAPI=1
+# export WANT_TCP_ZEBRA=0
+# export WANT_BGP_VNC=0
+# export WANT_CUMULUS_MODE=0
+# export WANT_MULTIPATH=1
+#
+# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
+# Please be aware that 0 is NOT disabled, but treated as unlimited
+# export MULTIPATH=256
+#
+# Set the following to the value required (or leave undefined for the default below)
+# WANT_FRR_USER is used for the username and groupname of the FRR user account
+# export WANT_FRR_USER=frr
+# export WANT_FRR_VTY_GROUP=frrvty
+#
+####################################
+
+export DH_VERBOSE=1
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+export DH_OPTIONS=-v
+
+ifeq ($(WANT_SNMP), 1)
+ USE_SNMP=--enable-snmp
+ $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience")
+else
+ $(warning "DEBIAN: SNMP disabled, see README.Debian")
+endif
+
+ifneq ($(WANT_LDP), 0)
+ USE_LDP=--enable-ldpd
+else
+ USE_LDP=--disable-ldpd
+endif
+
+ifneq ($(WANT_PIM), 0)
+ USE_PIM=--enable-pimd
+else
+ USE_PIM=--disable-pimd
+endif
+
+ifneq ($(WANT_OSPFAPI), 0)
+ USE_OSPFAPI=--enable-ospfapi=yes
+else
+ USE_OSPFAPI=--enable-ospfapi=no
+endif
+
+ifeq ($(WANT_TCP_ZEBRA),1)
+ USE_TCP_ZEBRA=--enable-tcp-zebra
+endif
+
+ifneq ($(WANT_BGP_VNC), 0)
+ USE_BGP_VNC=--enable-bgp-vnc=yes
+else
+ USE_BGP_VNC=--enable-bgp-vnc=no
+endif
+
+ifndef WANT_FRR_USER
+ USE_FRR_USER=--enable-user=frr
+ USE_FRR_GROUP=--enable-group=frr
+else
+ USE_FRR_USER=$(WANT_FRR_USER)
+ USE_FRR_GROUP=$(WANT_FRR_USER)
+endif
+
+ifndef WANT_FRR_VTY_GROUP
+ USE_FRR_VTY_GROUP=--enable-vty-group=frrvty
+else
+ USE_FRR_VTY_GROUP=--enable-vty-group=$(WANT_FRR_VTY_GROUP)
+endif
+
+ifneq ($(WANT_MULTIPATH), 0)
+ ifdef MULTIPATH
+ USE_MULTIPATH=--enable-multipath=$(MULTIPATH)
+ else
+ USE_MULTIPATH=--enable-multipath=256
+ endif
+else
+ USE_MULTIPATH=--disable-multipath
+endif
+
+ifeq ($(WANT_CUMULUS_NODE), 1)
+ USE_CUMULUS=--enable-cumulus=yes
+else
+ USE_CUMULUS=--enable-cumulus=no
+endif
+
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+ DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+endif
+
+ifdef DEBIAN_JOBS
+MAKEFLAGS += -j$(DEBIAN_JOBS)
+endif
+
+%:
+ dh $@ --with=systemd,autoreconf --parallel --dbg-package=frr-dbg --list-missing
+
+override_dh_auto_configure:
+ # Frr needs /proc to check some BSD vs Linux specific stuff.
+ # Else it fails with an obscure error message pointing out that
+ # IPCTL_FORWARDING is an undefined symbol which is not very helpful.
+ @if ! [ -d /proc/1 ]; then \
+ echo "./configure needs a mounted /proc"; \
+ exit 1; \
+ fi
+
+ if ! [ -e config.status ]; then \
+ dh_auto_configure -- \
+ --enable-exampledir=/usr/share/doc/frr/examples/ \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ $(USE_SNMP) \
+ $(USE_OSPFAPI) \
+ $(USE_MULTIPATH) \
+ $(USE_LDP) \
+ $(USE_TCP_ZEBRA) \
+ --enable-fpm \
+ $(USE_FRR_USER) $(USE_FRR_GROUP) \
+ $(USE_FRR_VTY_GROUP) \
+ --enable-configfile-mask=0640 \
+ --enable-logfile-mask=0640 \
+ --enable-werror \
+ --with-libpam \
+ --enable-systemd=yes \
+ --enable-poll=yes \
+ $(USE_CUMULUS) \
+ $(USE_PIM) \
+ --enable-dependency-tracking \
+ $(USE_BGP_VNC) \
+ $(shell dpkg-buildflags --export=configure); \
+ fi
+
+override_dh_auto_build:
+ #dh_auto_build
+ $(MAKE)
+ dh_auto_build -- -C doc draft-zebra-00.txt
+
+
+ # doc/ is a bit crazy
+ifeq ($(GENERATE_PDF), 1)
+ dh_auto_build -- -C doc frr.pdf || true # pdfetex fails with exit code 1 but still produces a good looking .pdf
+endif
+ rm -vf doc/frr.info
+ dh_auto_build -- -C doc frr.info
+ rm -vf doc/frr.info.html*
+
+override_dh_auto_test:
+
+override_dh_auto_install:
+ dh_auto_install
+
+ # installed in frr-pythontools
+ rm debian/tmp/usr/lib/frr/frr-reload.py
+
+ # cleaning up the info dir
+ rm -f debian/tmp/usr/share/info/dir*
+
+ # install config files
+ mkdir -p debian/tmp/etc/frr/
+ perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
+
+ # installing the Frr specific SNMP MIB
+ifeq ($(WANT_SNMP), 1)
+ install -D -m 644 ./zebra/GNOME-PRODUCT-ZEBRA-MIB debian/tmp/usr/share/snmp/mibs/GNOME-PRODUCT-ZEBRA-MIB
+else
+ mkdir -p debian/tmp/usr/share/snmp/mibs/
+endif
+
+ # cleaning .la files
+ sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
+ sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la
+
+override_dh_systemd_start:
+ dh_systemd_start frr.service
+
+override_dh_systemd_enable:
+ dh_systemd_enable frr.service
+
+# backports
+SRCPKG = frr
+KNOWN_BACKPORTS = debian8 debian9 ubuntu12.04 ubuntu14.04 ubuntu16.04
+DEBIAN_VERSION := $(shell dh_testdir && \
+ dpkg-parsechangelog -c1 < debian/changelog | \
+ sed -rn 's/^Version: ?//p')
+ORIG_VERSION := $(DEBIAN_VERSION)
+-include debian/backports/rules
+
+ifneq ($(TARBALLDIR),)
+ifeq ($(wildcard frr-$(ORIG_VERSION).tar.gz),frr-$(ORIG_VERSION).tar.gz)
+
+$(TARBALLDIR)/$(SRCPKG)_$(ORIG_VERSION).orig.tar.gz: \
+ frr-$(ORIG_VERSION).tar.gz
+ cp $< $@
+
+else # wildcard frr-$(ORIG_VERSION).tar.gz
+
+# better error message on missing .orig.tar.gz
+$(TARBALLDIR)/$(SRCPKG)_$(ORIG_VERSION).orig.tar.gz:
+ @ echo "\`$(TARBALLDIR)/$(SRCPKG)-$(ORIG_VERSION).tar.gz'" not \
+ found and not generated by debian/rules. Provided you have the \
+ necessary packages installed, you can generate it yourself via \
+ "\"./bootstrap.sh && ./configure && make dist\"".
+ exit 1
+
+endif # wildcard frr-$(ORIG_VERSION).tar.gz
+endif # TARBALLDIR nonempty
diff --git a/debian/source/format b/debianpkg/source/format
index af745b310b..af745b310b 100644
--- a/debian/source/format
+++ b/debianpkg/source/format
diff --git a/debian/tests/control b/debianpkg/tests/control
index 53fd537e2e..53fd537e2e 100644
--- a/debian/tests/control
+++ b/debianpkg/tests/control
diff --git a/debian/tests/daemons b/debianpkg/tests/daemons
index ac35ecd950..ac35ecd950 100644
--- a/debian/tests/daemons
+++ b/debianpkg/tests/daemons
diff --git a/debian/watchfrr.rc b/debianpkg/watchfrr.rc
index 4110b86399..4110b86399 100644
--- a/debian/watchfrr.rc
+++ b/debianpkg/watchfrr.rc
diff --git a/doc/Building_FRR_on_Debian9.md b/doc/Building_FRR_on_Debian9.md
new file mode 100644
index 0000000000..1536c25932
--- /dev/null
+++ b/doc/Building_FRR_on_Debian9.md
@@ -0,0 +1,121 @@
+Building FRR on Debian 9 from Git Source
+========================================
+
+Install required packages
+-------------------------
+
+Add packages:
+
+ sudo apt-get install git autoconf automake libtool make \
+ libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
+ python-pip libc-ares-dev python3-dev python-pytest
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not using
+any packages**
+
+### Add frr groups and user
+
+ sudo addgroup --system --gid 92 frr
+ sudo addgroup --system --gid 85 frrvty
+ sudo adduser --system --ingroup frr --home /var/run/frr/ \
+ --gecos "FRR suite" --shell /bin/false frr
+ sudo usermod -a -G frrvty frr
+
+### Download Source, configure and compile it
+(You may prefer different options on configure statement. These are just
+an example.)
+
+ git clone https://github.com/frrouting/frr.git frr
+ cd frr
+ git checkout stable/3.0
+ ./bootstrap.sh
+ ./configure \
+ --enable-exampledir=/usr/share/doc/frr/examples/ \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ --enable-vtysh \
+ --enable-isisd \
+ --enable-pimd \
+ --enable-watchfrr \
+ --enable-ospfclient=yes \
+ --enable-ospfapi=yes \
+ --enable-multipath=64 \
+ --enable-user=frr \
+ --enable-group=frr \
+ --enable-vty-group=frrvty \
+ --enable-configfile-mask=0640 \
+ --enable-logfile-mask=0640 \
+ --enable-rtadv \
+ --enable-fpm \
+ --enable-ldpd \
+ --with-pkg-git-version \
+ --with-pkg-extra-version=-MyOwnFRRVersion
+ make
+ make check
+ sudo make install
+
+### Create empty FRR configuration files
+
+ sudo install -m 755 -o frr -g frr -d /var/log/frr
+ sudo install -m 775 -o frr -g frrvty -d /etc/frr
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+ sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
+
+### Enable IP & IPv6 forwarding
+
+Edit `/etc/sysctl.conf` and uncomment the following values (ignore the
+other settings)
+
+ # Uncomment the next line to enable packet forwarding for IPv4
+ net.ipv4.ip_forward=1
+
+ # Uncomment the next line to enable packet forwarding for IPv6
+ # Enabling this option disables Stateless Address Autoconfiguration
+ # based on Router Advertisements for this host
+ net.ipv6.conf.all.forwarding=1
+
+**Reboot** or use `sysctl -p` to apply the same config to the running system
+
+### Troubleshooting
+
+**Local state directory**
+
+The local state directory must exist and have the correct permissions applied
+for the frrouting daemons to start. In the above ./configure example the
+local state directory is set to /var/run/frr (--localstatedir=/var/run/frr)
+Debian considers /var/run/frr to be temporary and this is removed after a
+reboot.
+
+When using a different local state directory you need to create the new
+directory and change the ownership to the frr user, for example:
+
+ mkdir /var/opt/frr
+ chown frr /var/opt/frr
+
+**Shared library error**
+
+If you try and start any of the frrouting daemons you may see the below error
+due to the frrouting shared library directory not being found:
+
+ ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory
+
+The fix is to add the following line to /etc/ld.so.conf which will continue to
+reference the library directory after the system reboots. To load the library
+directory path immediately run the ldconfig command after adding the line to
+the file eg:
+
+ echo include /usr/local/lib >> /etc/ld.so.conf
+ ldconfig
diff --git a/doc/install.texi b/doc/install.texi
index 1930af95e6..19d9614420 100644
--- a/doc/install.texi
+++ b/doc/install.texi
@@ -101,6 +101,10 @@ needs libexecinfo, while on glibc support for this is part of libc itself.
Turn on some options for compiling FRR within a development environment in
mind. Specifically turn on -g3 -O0 for compiling options and add inclusion
of grammar sandbox.
+@item --enable-fuzzing
+Turn on some compile options to allow you to run fuzzing tools
+against the system. This tools is intended as a developer
+only tool and should not be used for normal operations
@end table
You may specify any combination of the above options to the configure
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 9076a50f57..00438f2f47 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -94,6 +94,18 @@ static int eigrp_router_id_update_zebra(int command, struct zclient *zclient,
return 0;
}
+static int eigrp_zebra_notify_owner(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct prefix p;
+ enum zapi_route_notify_owner note;
+
+ if (!zapi_route_notify_decode(zclient->ibuf, &p, &note))
+ return -1;
+
+ return 0;
+}
+
static void eigrp_zebra_connected(struct zclient *zclient)
{
zclient_send_reg_requests(zclient, VRF_DEFAULT);
@@ -101,7 +113,9 @@ static void eigrp_zebra_connected(struct zclient *zclient)
void eigrp_zebra_init(void)
{
- zclient = zclient_new(master);
+ struct zclient_options opt = { .receive_notify = false };
+
+ zclient = zclient_new_notify(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
zclient->zebra_connected = eigrp_zebra_connected;
@@ -114,6 +128,7 @@ void eigrp_zebra_init(void)
zclient->interface_address_delete = eigrp_interface_address_delete;
zclient->redistribute_route_add = eigrp_zebra_read_route;
zclient->redistribute_route_del = eigrp_zebra_read_route;
+ zclient->notify_owner = eigrp_zebra_notify_owner;
}
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index c186dd56ad..573b81591c 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -411,7 +411,7 @@ static void isis_zebra_connected(struct zclient *zclient)
void isis_zebra_init(struct thread_master *master)
{
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
zclient->router_id_update = isis_router_id_update_zebra;
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 8122b88cca..b597d967d7 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -1618,7 +1618,7 @@ static void
zclient_sync_init(u_short instance)
{
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master);
+ zclient_sync = zclient_new_notify(master, &zclient_options_default);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
zclient_sync->instance = instance;
diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c
index aa2e06dfb9..6c86582960 100644
--- a/ldpd/ldp_vty_cmds.c
+++ b/ldpd/ldp_vty_cmds.c
@@ -25,7 +25,9 @@
#include "ldpd/ldpd.h"
#include "ldpd/ldp_vty.h"
+#ifndef VTYSH_EXTRACT_PL
#include "ldpd/ldp_vty_cmds_clippy.c"
+#endif
DEFUN_NOSH(ldp_mpls_ldp,
ldp_mpls_ldp_cmd,
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 8fe51cb9d1..e703a9ff61 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -513,7 +513,7 @@ void
ldp_zebra_init(struct thread_master *master)
{
/* Set default values. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
/* set callbacks */
diff --git a/lib/log.c b/lib/log.c
index 02af55d465..7589934b69 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -897,6 +897,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_INTERFACE_SET_MASTER),
DESC_ENTRY(ZEBRA_ROUTE_ADD),
DESC_ENTRY(ZEBRA_ROUTE_DELETE),
+ DESC_ENTRY(ZEBRA_ROUTE_NOTIFY_OWNER),
DESC_ENTRY(ZEBRA_IPV4_ROUTE_ADD),
DESC_ENTRY(ZEBRA_IPV4_ROUTE_DELETE),
DESC_ENTRY(ZEBRA_IPV6_ROUTE_ADD),
@@ -1044,6 +1045,8 @@ int proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_NHRP;
else if (strmatch(s, "babel"))
return ZEBRA_ROUTE_BABEL;
+ else if (strmatch(s, "sharp"))
+ return ZEBRA_ROUTE_SHARP;
}
if (afi == AFI_IP6) {
if (strmatch(s, "kernel"))
@@ -1070,6 +1073,8 @@ int proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_NHRP;
else if (strmatch(s, "babel"))
return ZEBRA_ROUTE_BABEL;
+ else if (strmatch(s, "sharp"))
+ return ZEBRA_ROUTE_SHARP;
}
return -1;
}
diff --git a/lib/route_types.txt b/lib/route_types.txt
index 386d9992f7..4e764a14c1 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -77,6 +77,7 @@ ZEBRA_ROUTE_BGP_DIRECT, bgp-direct, NULL, 'b', 0, 0, "BGP-Direct"
# bgp unicast -> vnc
ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC"
ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel"
+ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, "SHARP"
ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, "-"
@@ -101,3 +102,4 @@ ZEBRA_ROUTE_TABLE, "Non-main Kernel Routing Table"
ZEBRA_ROUTE_LDP, "Label Distribution Protocol (LDP)"
ZEBRA_ROUTE_VNC_DIRECT, "VNC direct (not via zebra) routes"
ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)"
+ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)"
diff --git a/lib/zclient.c b/lib/zclient.c
index 6d6d44fb12..655e4e1a80 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -52,8 +52,11 @@ socklen_t zclient_addr_len;
/* This file local debug flag. */
int zclient_debug = 0;
+struct zclient_options zclient_options_default = { .receive_notify = false };
+
/* Allocate zclient structure. */
-struct zclient *zclient_new(struct thread_master *master)
+struct zclient *zclient_new_notify(struct thread_master *master,
+ struct zclient_options *opt)
{
struct zclient *zclient;
zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
@@ -63,6 +66,8 @@ struct zclient *zclient_new(struct thread_master *master)
zclient->wb = buffer_new(0);
zclient->master = master;
+ zclient->receive_notify = opt->receive_notify;
+
return zclient;
}
@@ -190,7 +195,7 @@ void zclient_reset(struct zclient *zclient)
* @param zclient a pointer to zclient structure
* @return socket fd just to make sure that connection established
* @see zclient_init
- * @see zclient_new
+ * @see zclient_new_notify
*/
int zclient_socket_connect(struct zclient *zclient)
{
@@ -346,6 +351,11 @@ static int zebra_hello_send(struct zclient *zclient)
zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
stream_putc(s, zclient->redist_default);
stream_putw(s, zclient->instance);
+ if (zclient->receive_notify)
+ stream_putc(s, 1);
+ else
+ stream_putc(s, 0);
+
stream_putw_at(s, 0, stream_get_endp(s));
return zclient_send_message(zclient);
}
@@ -1144,6 +1154,22 @@ stream_failure:
return 0;
}
+bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
+ enum zapi_route_notify_owner *note)
+{
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETC(s, p->family);
+ STREAM_GETC(s, p->prefixlen);
+ STREAM_GET(&p->u.prefix, s,
+ PSIZE(p->prefixlen));
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
/*
* send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
* for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
@@ -2194,6 +2220,11 @@ static int zclient_read(struct thread *thread)
(*zclient->pw_status_update)(command, zclient, length,
vrf_id);
break;
+ case ZEBRA_ROUTE_NOTIFY_OWNER:
+ if (zclient->notify_owner)
+ (*zclient->notify_owner)(command, zclient,
+ length, vrf_id);
+ break;
default:
break;
}
diff --git a/lib/zclient.h b/lib/zclient.h
index e9b2cb8956..de58044671 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -61,6 +61,7 @@ typedef enum {
ZEBRA_INTERFACE_SET_MASTER,
ZEBRA_ROUTE_ADD,
ZEBRA_ROUTE_DELETE,
+ ZEBRA_ROUTE_NOTIFY_OWNER,
ZEBRA_IPV4_ROUTE_ADD,
ZEBRA_IPV4_ROUTE_DELETE,
ZEBRA_IPV6_ROUTE_ADD,
@@ -137,6 +138,9 @@ struct zclient {
/* Priviledges to change socket values */
struct zebra_privs_t *privs;
+ /* Do we care about failure events for route install? */
+ bool receive_notify;
+
/* Socket to zebra daemon. */
int sock;
@@ -199,6 +203,8 @@ struct zclient {
int (*local_macip_add)(int, struct zclient *, uint16_t, vrf_id_t);
int (*local_macip_del)(int, struct zclient *, uint16_t, vrf_id_t);
int (*pw_status_update)(int, struct zclient *, uint16_t, vrf_id_t);
+ int (*notify_owner)(int command, struct zclient *zclient,
+ uint16_t length, vrf_id_t vrf_id);
};
/* Zebra API message flag. */
@@ -323,12 +329,35 @@ struct zapi_pw_status {
uint32_t status;
};
+enum zapi_route_notify_owner {
+ ZAPI_ROUTE_FAIL_INSTALL,
+ ZAPI_ROUTE_BETTER_ADMIN_WON,
+ ZAPI_ROUTE_INSTALLED,
+};
+
/* Zebra MAC types */
#define ZEBRA_MAC_TYPE_STICKY 0x01 /* Sticky MAC*/
#define ZEBRA_MAC_TYPE_GW 0x02 /* gateway (SVI) mac*/
+struct zclient_options {
+ bool receive_notify;
+};
+
/* Prototypes of zebra client service functions. */
extern struct zclient *zclient_new(struct thread_master *);
+
+#if CONFDATE > 20181101
+CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
+#endif
+
+extern struct zclient_options zclient_options_default;
+
+extern struct zclient *zclient_new_notify(struct thread_master *m,
+ struct zclient_options *opt);
+
+#define zclient_new(A) zclient_new_notify((A), &zclient_options_default); \
+ CPP_WARN("Please transition to using zclient_new_notify");
+
extern void zclient_init(struct zclient *, int, u_short, struct zebra_privs_t *privs);
extern int zclient_start(struct zclient *);
extern void zclient_stop(struct zclient *);
@@ -445,6 +474,8 @@ extern int zapi_ipv4_route_ipv6_nexthop(u_char, struct zclient *,
extern int zclient_route_send(u_char, struct zclient *, struct zapi_route *);
extern int zapi_route_encode(u_char, struct stream *, struct zapi_route *);
extern int zapi_route_decode(struct stream *, struct zapi_route *);
+bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
+ enum zapi_route_notify_owner *note);
static inline void zapi_route_set_blackhole(struct zapi_route *api,
enum blackhole_type bh_type)
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 7701dcbb88..2612d8e045 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -314,7 +314,7 @@ void nhrp_zebra_init(void)
zebra_rib[AFI_IP] = route_table_init();
zebra_rib[AFI_IP6] = route_table_init();
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient->zebra_connected = nhrp_zebra_connected;
zclient->interface_add = nhrp_interface_add;
zclient->interface_delete = nhrp_interface_delete;
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index a900648236..cc87c499ee 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -583,7 +583,7 @@ static void ospf6_zebra_connected(struct zclient *zclient)
void ospf6_zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected;
zclient->router_id_update = ospf6_router_id_update_zebra;
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 89c462693b..33461e6df8 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -127,7 +127,8 @@ int ospf_route_map_set_compare(struct route_map_set_values *values1,
}
/* Add an External info for AS-external-LSA. */
-struct external_info *ospf_external_info_add(u_char type, u_short instance,
+struct external_info *ospf_external_info_add(struct ospf *ospf, u_char type,
+ u_short instance,
struct prefix_ipv4 p,
ifindex_t ifindex,
struct in_addr nexthop,
@@ -138,9 +139,9 @@ struct external_info *ospf_external_info_add(u_char type, u_short instance,
struct ospf_external *ext;
char inetbuf[INET6_BUFSIZ];
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (!ext)
- ext = ospf_external_add(type, instance);
+ ext = ospf_external_add(ospf, type, instance);
rn = route_node_get(EXTERNAL_INFO(ext), (struct prefix *)&p);
/* If old info exists, -- discard new one or overwrite with new one? */
@@ -157,9 +158,10 @@ struct external_info *ospf_external_info_add(u_char type, u_short instance,
inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
INET6_BUFSIZ);
zlog_warn(
- "Redistribute[%s][%d]: %s/%d discarding old info with NH %s.",
+ "Redistribute[%s][%d][%u]: %s/%d discarding old info with NH %s.",
ospf_redist_string(type), instance,
- inet_ntoa(p.prefix), p.prefixlen, inetbuf);
+ ospf->vrf_id, inet_ntoa(p.prefix),
+ p.prefixlen, inetbuf);
XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info);
rn->info = NULL;
}
@@ -179,20 +181,20 @@ struct external_info *ospf_external_info_add(u_char type, u_short instance,
inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
INET6_BUFSIZ);
zlog_debug(
- "Redistribute[%s]: %s/%d external info created, with NH %s",
- ospf_redist_string(type), inet_ntoa(p.prefix),
- p.prefixlen, inetbuf);
+ "Redistribute[%s][%u]: %s/%d external info created, with NH %s",
+ ospf_redist_string(type), ospf->vrf_id,
+ inet_ntoa(p.prefix), p.prefixlen, inetbuf);
}
return new;
}
-void ospf_external_info_delete(u_char type, u_short instance,
+void ospf_external_info_delete(struct ospf *ospf, u_char type, u_short instance,
struct prefix_ipv4 p)
{
struct route_node *rn;
struct ospf_external *ext;
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (!ext)
return;
@@ -205,13 +207,14 @@ void ospf_external_info_delete(u_char type, u_short instance,
}
}
-struct external_info *ospf_external_info_lookup(u_char type, u_short instance,
+struct external_info *ospf_external_info_lookup(struct ospf *ospf, u_char type,
+ u_short instance,
struct prefix_ipv4 *p)
{
struct route_node *rn;
struct ospf_external *ext;
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (!ext)
return NULL;
@@ -288,7 +291,7 @@ void ospf_redistribute_withdraw(struct ospf *ospf, u_char type,
struct external_info *ei;
struct ospf_external *ext;
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (!ext)
return;
diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h
index 3d7f14e7f2..38ed95322b 100644
--- a/ospfd/ospf_asbr.h
+++ b/ospfd/ospf_asbr.h
@@ -58,12 +58,15 @@ extern struct external_info *ospf_external_info_new(u_char, u_short);
extern void ospf_reset_route_map_set_values(struct route_map_set_values *);
extern int ospf_route_map_set_compare(struct route_map_set_values *,
struct route_map_set_values *);
-extern struct external_info *ospf_external_info_add(u_char, u_short,
+extern struct external_info *ospf_external_info_add(struct ospf *,
+ u_char, u_short,
struct prefix_ipv4,
ifindex_t, struct in_addr,
route_tag_t);
-extern void ospf_external_info_delete(u_char, u_short, struct prefix_ipv4);
-extern struct external_info *ospf_external_info_lookup(u_char, u_short,
+extern void ospf_external_info_delete(struct ospf*, u_char, u_short,
+ struct prefix_ipv4);
+extern struct external_info *ospf_external_info_lookup(struct ospf*, u_char,
+ u_short,
struct prefix_ipv4 *);
extern struct ospf_route *ospf_external_route_lookup(struct ospf *,
struct prefix_ipv4 *);
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index aac2f3ee92..36b6d5143d 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -108,7 +108,7 @@ struct external_info *ospf_external_info_check(struct ospf *ospf,
struct listnode *node;
struct ospf_external *ext;
- ext_list = om->external[type];
+ ext_list = ospf->external[type];
if (!ext_list)
continue;
@@ -361,9 +361,9 @@ static int ospf_flood_through_interface(struct ospf_interface *oi,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_flood_through_interface(): "
- "considering int %s, INBR(%s), LSA[%s]",
+ "considering int %s, INBR(%s), LSA[%s] AGE %u",
IF_NAME(oi), inbr ? inet_ntoa(inbr->router_id) : "NULL",
- dump_lsa_key(lsa));
+ dump_lsa_key(lsa), ntohs(lsa->data->ls_age));
if (!ospf_if_is_enable(oi))
return 0;
@@ -958,6 +958,9 @@ void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area)
more time for the ACK to be received and avoid
retransmissions */
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: MAXAGE set to LSA %s", __PRETTY_FUNCTION__,
+ inet_ntoa(lsa->data->id));
monotime(&lsa->tv_recv);
lsa->tv_orig = lsa->tv_recv;
ospf_flood_through_area(area, NULL, lsa);
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 4e67694059..c28e500d5b 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2037,7 +2037,7 @@ int ospf_external_lsa_originate_timer(struct thread *thread)
ospf->t_external_lsa = NULL;
- ext_list = om->external[type];
+ ext_list = ospf->external[type];
if (!ext_list)
return 0;
@@ -2077,7 +2077,7 @@ static struct external_info *ospf_default_external_info(struct ospf *ospf)
if (type == ZEBRA_ROUTE_OSPF)
continue;
- ext_list = om->external[type];
+ ext_list = ospf->external[type];
if (!ext_list)
continue;
@@ -2114,7 +2114,8 @@ int ospf_default_originate_timer(struct thread *thread)
/* If there is no default route via redistribute,
then originate AS-external-LSA with nexthop 0 (self). */
nexthop.s_addr = 0;
- ospf_external_info_add(DEFAULT_ROUTE, 0, p, 0, nexthop, 0);
+ ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, p, 0,
+ nexthop, 0);
}
if ((ei = ospf_default_external_info(ospf)))
@@ -2245,25 +2246,32 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, u_char type,
struct external_info *ei;
struct ospf_external *ext;
- if (type != DEFAULT_ROUTE)
- if ((ext = ospf_external_lookup(type, instance))
- && EXTERNAL_INFO(ext))
- /* Refresh each redistributed AS-external-LSAs. */
- for (rn = route_top(EXTERNAL_INFO(ext)); rn;
- rn = route_next(rn))
- if ((ei = rn->info))
- if (!is_prefix_default(&ei->p)) {
- struct ospf_lsa *lsa;
-
- if ((lsa = ospf_external_info_find_lsa(
- ospf, &ei->p)))
- ospf_external_lsa_refresh(
- ospf, lsa, ei,
- force);
- else
- ospf_external_lsa_originate(
- ospf, ei);
- }
+ if (type == DEFAULT_ROUTE)
+ return;
+
+ ext = ospf_external_lookup(ospf, type, instance);
+
+ if (ext && EXTERNAL_INFO(ext)) {
+ /* Refresh each redistributed AS-external-LSAs. */
+ for (rn = route_top(EXTERNAL_INFO(ext)); rn;
+ rn = route_next(rn)) {
+ ei = rn->info;
+ if (ei) {
+ if (!is_prefix_default(&ei->p)) {
+ struct ospf_lsa *lsa;
+
+ lsa = ospf_external_info_find_lsa(ospf,
+ &ei->p);
+ if (lsa)
+ ospf_external_lsa_refresh(ospf,
+ lsa, ei, force);
+ else
+ ospf_external_lsa_originate(ospf
+ , ei);
+ }
+ }
+ }
+ }
}
/* Refresh AS-external-LSA. */
@@ -3302,6 +3310,8 @@ void ospf_flush_self_originated_lsas_now(struct ospf *ospf)
struct route_node *rn;
int need_to_flush_ase = 0;
+ ospf->inst_shutdown = 1;
+
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
if ((lsa = area->router_lsa_self) != NULL) {
if (IS_DEBUG_OSPF_EVENT)
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 633c3deeaf..33792bbff3 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -518,7 +518,8 @@ int ospf_ls_upd_timer(struct thread *thread)
}
if (listcount(update) > 0)
- ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT);
+ ospf_ls_upd_send(nbr, update,
+ OSPF_SEND_PACKET_DIRECT, 0);
list_delete_and_null(&update);
}
@@ -1609,10 +1610,10 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
if (length + ntohs(find->data->length) > ospf_packet_max(oi)) {
if (oi->type == OSPF_IFTYPE_NBMA)
ospf_ls_upd_send(nbr, ls_upd,
- OSPF_SEND_PACKET_DIRECT);
+ OSPF_SEND_PACKET_DIRECT, 0);
else
ospf_ls_upd_send(nbr, ls_upd,
- OSPF_SEND_PACKET_INDIRECT);
+ OSPF_SEND_PACKET_INDIRECT, 0);
/* Only remove list contents. Keep ls_upd. */
list_delete_all_node(ls_upd);
@@ -1630,10 +1631,11 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
/* Send rest of Link State Update. */
if (listcount(ls_upd) > 0) {
if (oi->type == OSPF_IFTYPE_NBMA)
- ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
+ ospf_ls_upd_send(nbr, ls_upd,
+ OSPF_SEND_PACKET_DIRECT, 0);
else
ospf_ls_upd_send(nbr, ls_upd,
- OSPF_SEND_PACKET_INDIRECT);
+ OSPF_SEND_PACKET_INDIRECT, 0);
list_delete_and_null(&ls_upd);
} else
@@ -3792,7 +3794,13 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
update = list_new();
listnode_add(update, lsa);
- ospf_ls_upd_send(nbr, update, flag);
+
+ /*ospf instance is going down, send self originated
+ * MAXAGE LSA update to neighbors to remove from LSDB */
+ if (nbr->oi->ospf->inst_shutdown && IS_LSA_MAXAGE(lsa))
+ ospf_ls_upd_send(nbr, update, flag, 1);
+ else
+ ospf_ls_upd_send(nbr, update, flag, 0);
list_delete_and_null(&update);
}
@@ -3875,7 +3883,8 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update,
}
static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
- struct list *update, struct in_addr addr)
+ struct list *update, struct in_addr addr,
+ int send_lsupd_now)
{
struct ospf_packet *op;
u_int16_t length = OSPF_HEADER_SIZE;
@@ -3908,9 +3917,20 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
/* Add packet to the interface output queue. */
ospf_packet_add(oi, op);
-
- /* Hook thread to write packet. */
- OSPF_ISM_WRITE_ON(oi->ospf);
+ /* Call ospf_write() right away to send ospf packets to neighbors */
+ if (send_lsupd_now) {
+ struct thread os_packet_thd;
+
+ os_packet_thd.arg = (void *)oi->ospf;
+ if (oi->on_write_q == 0) {
+ listnode_add(oi->ospf->oi_write_q, oi);
+ oi->on_write_q = 1;
+ }
+ ospf_write(&os_packet_thd);
+ } else {
+ /* Hook thread to write packet. */
+ OSPF_ISM_WRITE_ON(oi->ospf);
+ }
}
static int ospf_ls_upd_send_queue_event(struct thread *thread)
@@ -3934,7 +3954,7 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread)
update = (struct list *)rn->info;
- ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4);
+ ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4, 0);
/* list might not be empty. */
if (listcount(update) == 0) {
@@ -3961,7 +3981,8 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread)
return 0;
}
-void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag)
+void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag,
+ int send_lsupd_now)
{
struct ospf_interface *oi;
struct ospf_lsa *lsa;
@@ -4006,8 +4027,24 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag)
for (ALL_LIST_ELEMENTS_RO(update, node, lsa))
listnode_add(rn->info,
ospf_lsa_lock(lsa)); /* oi->ls_upd_queue */
+ if (send_lsupd_now) {
+ struct list *send_update_list;
+ struct route_node *rn, *rnext;
- thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ for (rn = route_top(oi->ls_upd_queue); rn; rn = rnext) {
+ rnext = route_next(rn);
+
+ if (rn->info == NULL)
+ continue;
+
+ send_update_list = (struct list *)rn->info;
+
+ ospf_ls_upd_queue_send(oi, send_update_list,
+ rn->p.u.prefix4, 1);
+
+ }
+ } else
+ thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
&oi->t_ls_upd_event);
}
diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
index a3617c7bda..78b2b81e50 100644
--- a/ospfd/ospf_packet.h
+++ b/ospfd/ospf_packet.h
@@ -152,7 +152,7 @@ extern void ospf_db_desc_resend(struct ospf_neighbor *);
extern void ospf_ls_req_send(struct ospf_neighbor *);
extern void ospf_ls_upd_send_lsa(struct ospf_neighbor *, struct ospf_lsa *,
int);
-extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int);
+extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int, int);
extern void ospf_ls_ack_send(struct ospf_neighbor *, struct ospf_lsa *);
extern void ospf_ls_ack_send_delayed(struct ospf_interface *);
extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index a49143873e..fef274bba3 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -8361,10 +8361,10 @@ DEFUN (no_ospf_default_information_originate,
ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0);
- if ((ext = ospf_external_lookup(DEFAULT_ROUTE, 0))
- && EXTERNAL_INFO(ext)) {
- ospf_external_info_delete(DEFAULT_ROUTE, 0, p);
- ospf_external_del(DEFAULT_ROUTE, 0);
+ ext = ospf_external_lookup(ospf, DEFAULT_ROUTE, 0);
+ if (ext && EXTERNAL_INFO(ext)) {
+ ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, p);
+ ospf_external_del(ospf, DEFAULT_ROUTE, 0);
}
red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index d7fe0edcbf..66be29dbb4 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -519,13 +519,14 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
inet_ntoa(p->prefix), p->prefixlen);
}
-struct ospf_external *ospf_external_lookup(u_char type, u_short instance)
+struct ospf_external *ospf_external_lookup(struct ospf *ospf, u_char type,
+ u_short instance)
{
struct list *ext_list;
struct listnode *node;
struct ospf_external *ext;
- ext_list = om->external[type];
+ ext_list = ospf->external[type];
if (!ext_list)
return (NULL);
@@ -536,19 +537,20 @@ struct ospf_external *ospf_external_lookup(u_char type, u_short instance)
return NULL;
}
-struct ospf_external *ospf_external_add(u_char type, u_short instance)
+struct ospf_external *ospf_external_add(struct ospf *ospf, u_char type,
+ u_short instance)
{
struct list *ext_list;
struct ospf_external *ext;
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (ext)
return ext;
- if (!om->external[type])
- om->external[type] = list_new();
+ if (!ospf->external[type])
+ ospf->external[type] = list_new();
- ext_list = om->external[type];
+ ext_list = ospf->external[type];
ext = (struct ospf_external *)XCALLOC(MTYPE_OSPF_EXTERNAL,
sizeof(struct ospf_external));
ext->instance = instance;
@@ -559,20 +561,21 @@ struct ospf_external *ospf_external_add(u_char type, u_short instance)
return ext;
}
-void ospf_external_del(u_char type, u_short instance)
+void ospf_external_del(struct ospf *ospf, u_char type, u_short instance)
{
struct ospf_external *ext;
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (ext) {
if (EXTERNAL_INFO(ext))
route_table_finish(EXTERNAL_INFO(ext));
- listnode_delete(om->external[type], ext);
- if (!om->external[type]->count) {
- list_delete_and_null(&om->external[type]);
- }
+ listnode_delete(ospf->external[type], ext);
+
+ if (!ospf->external[type]->count)
+ list_delete_and_null(&ospf->external[type]);
+
XFREE(MTYPE_OSPF_EXTERNAL, ext);
}
}
@@ -684,7 +687,7 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
red->dmetric.type = mtype;
red->dmetric.value = mvalue;
- ospf_external_add(type, instance);
+ ospf_external_add(ospf, type, instance);
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
instance, ospf->vrf_id);
@@ -720,7 +723,7 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance)
/* Remove the routes from OSPF table. */
ospf_redistribute_withdraw(ospf, type, instance);
- ospf_external_del(type, instance);
+ ospf_external_del(ospf, type, instance);
ospf_asbr_status_update(ospf, --ospf->redistribute);
@@ -738,7 +741,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
red->dmetric.type = mtype;
red->dmetric.value = mvalue;
- ospf_external_add(DEFAULT_ROUTE, 0);
+ ospf_external_add(ospf, DEFAULT_ROUTE, 0);
if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
/* if ospf->default_originate changes value, is calling
@@ -963,10 +966,11 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
*/
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != api.type)
- ospf_external_info_delete(i, api.instance, p);
+ ospf_external_info_delete(ospf, i,
+ api.instance, p);
- ei = ospf_external_info_add(api.type, api.instance, p, ifindex,
- nexthop, api.tag);
+ ei = ospf_external_info_add(ospf, api.type, api.instance, p,
+ ifindex, nexthop, api.tag);
if (ei == NULL) {
/* Nothing has changed, so nothing to do; return */
return 0;
@@ -1004,7 +1008,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
}
} else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
{
- ospf_external_info_delete(api.type, api.instance, p);
+ ospf_external_info_delete(ospf, api.type, api.instance, p);
if (is_prefix_default(&p))
ospf_external_lsa_refresh_default(ospf);
else
@@ -1087,7 +1091,7 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
struct listnode *node;
struct ospf_external *ext;
- ext_list = om->external[type];
+ ext_list = ospf->external[type];
if (!ext_list)
continue;
@@ -1130,7 +1134,7 @@ void ospf_distribute_list_update(struct ospf *ospf, int type,
args[1] = (void *)((ptrdiff_t) type);
/* External info does not exist. */
- ext = ospf_external_lookup(type, instance);
+ ext = ospf_external_lookup(ospf, type, instance);
if (!ext || !(rt = EXTERNAL_INFO(ext))) {
XFREE(MTYPE_OSPF_DIST_ARGS, args);
return;
@@ -1471,7 +1475,7 @@ static void ospf_zebra_connected(struct zclient *zclient)
void ospf_zebra_init(struct thread_master *master, u_short instance)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected;
zclient->router_id_update = ospf_router_id_update_zebra;
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 8340f49ede..d4b00dddff 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -59,9 +59,10 @@ extern int ospf_is_type_redistributed(struct ospf *, int, u_short);
extern void ospf_distance_reset(struct ospf *);
extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *,
struct ospf_route *);
-extern struct ospf_external *ospf_external_lookup(u_char, u_short);
-extern struct ospf_external *ospf_external_add(u_char, u_short);
-extern void ospf_external_del(u_char, u_short);
+extern struct ospf_external *ospf_external_lookup(struct ospf*, u_char,
+ u_short);
+extern struct ospf_external *ospf_external_add(struct ospf*, u_char, u_short);
+extern void ospf_external_del(struct ospf *, u_char, u_short);
extern struct ospf_redist *ospf_redist_lookup(struct ospf *, u_char, u_short);
extern struct ospf_redist *ospf_redist_add(struct ospf *, u_char, u_short);
extern void ospf_redist_del(struct ospf *, u_char, u_short);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index b0646495a5..ceb8440eeb 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -596,8 +596,7 @@ static void ospf_finish_final(struct ospf *ospf)
ospf_opaque_type11_lsa_term(ospf);
- /* be nice if this worked, but it doesn't */
- /*ospf_flush_self_originated_lsas_now (ospf);*/
+ ospf_flush_self_originated_lsas_now(ospf);
/* Unregister redistribution */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
@@ -742,7 +741,7 @@ static void ospf_finish_final(struct ospf *ospf)
struct listnode *node;
struct ospf_external *ext;
- ext_list = om->external[i];
+ ext_list = ospf->external[i];
if (!ext_list)
continue;
@@ -971,34 +970,37 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)
struct external_info *ei;
struct ospf_external *ext;
- if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0))
- if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0))
- && EXTERNAL_INFO(ext)) {
+ if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) {
+ ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0);
+ if ((ext) && EXTERNAL_INFO(ext)) {
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
rn = route_next(rn)) {
- if ((ei = rn->info) != NULL) {
- if (add_to_ospf) {
- if (ospf_external_info_find_lsa(
- ospf, &ei->p))
- if (!ospf_distribute_check_connected(
- ospf, ei))
- ospf_external_lsa_flush(
- ospf,
- ei->type,
- &ei->p,
- ei->ifindex /*, ei->nexthop */);
- } else {
- if (!ospf_external_info_find_lsa(
- ospf, &ei->p))
- if (ospf_distribute_check_connected(
- ospf, ei))
- ospf_external_lsa_originate(
- ospf,
- ei);
- }
+ ei = rn->info;
+ if (ei == NULL)
+ continue;
+
+ if (add_to_ospf) {
+ if (ospf_external_info_find_lsa(
+ ospf, &ei->p))
+ if (!ospf_distribute_check_connected(
+ ospf, ei))
+ ospf_external_lsa_flush(
+ ospf,
+ ei->type,
+ &ei->p,
+ ei->ifindex /*, ei->nexthop */);
+ } else {
+ if (!ospf_external_info_find_lsa(
+ ospf, &ei->p))
+ if (ospf_distribute_check_connected(
+ ospf, ei))
+ ospf_external_lsa_originate(
+ ospf,
+ ei);
}
}
}
+ }
}
/* Config network statement related functions. */
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index df318cf2c0..bd3be06646 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -93,11 +93,6 @@ struct ospf_master {
/* OSPF thread master. */
struct thread_master *master;
-
- /* Redistributed external information. */
- struct list *external[ZEBRA_ROUTE_MAX + 1];
-#define EXTERNAL_INFO(E) (E->external_info)
-
/* Various OSPF global configuration. */
u_char options;
#define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
@@ -310,6 +305,14 @@ struct ospf {
struct route_table *distance_table;
+ /* Used during ospf instance going down send LSDB
+ * update to neighbors immediatly */
+ uint8_t inst_shutdown;
+
+ /* Redistributed external information. */
+ struct list *external[ZEBRA_ROUTE_MAX + 1];
+#define EXTERNAL_INFO(E) (E->external_info)
+
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(ospf)
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 04466258bb..689e9a7449 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -748,7 +748,7 @@ void pim_zebra_init(void)
int i;
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient->zebra_connected = pim_zebra_connected;
zclient->router_id_update = pim_router_id_update_zebra;
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index fd75a699b3..bcaf4a38dd 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -120,7 +120,7 @@ void zclient_lookup_free(void)
void zclient_lookup_new(void)
{
- zlookup = zclient_new(master);
+ zlookup = zclient_new_notify(master, &zclient_options_default);
if (!zlookup) {
zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__);
return;
diff --git a/redhat/daemons b/redhat/daemons
index c163f4d2ce..889e288e57 100644
--- a/redhat/daemons
+++ b/redhat/daemons
@@ -49,6 +49,7 @@ pimd=no
nhrpd=no
eigrpd=no
babeld=no
+sharpd=no
#
# Command line options for the daemons
#
@@ -64,6 +65,7 @@ pimd_options=("-A 127.0.0.1")
nhrpd_options=("-A 127.0.0.1")
eigrpd_options=("-A 127.0.0.1")
babeld_options=("-A 127.0.0.1")
+sharpd_options=("-A 127.0.0.1")
#
# If the vtysh_enable is yes, then the unified config is read
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index a997ca5f2e..d20954037d 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -559,7 +559,7 @@ int rip_if_down(struct interface *ifp)
if ((list = rp->info) != NULL)
for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
rinfo))
- if (rinfo->ifindex == ifp->ifindex)
+ if (rinfo->nh.ifindex == ifp->ifindex)
rip_ecmp_delete(rinfo);
ri = ifp->info;
@@ -591,6 +591,7 @@ void rip_if_down_all()
static void rip_apply_address_add(struct connected *ifc)
{
struct prefix_ipv4 address;
+ struct nexthop nh;
struct prefix *p;
if (!rip)
@@ -602,18 +603,22 @@ static void rip_apply_address_add(struct connected *ifc)
p = ifc->address;
memset(&address, 0, sizeof(address));
+ memset(&nh, 0, sizeof(nh));
+
address.family = p->family;
address.prefix = p->u.prefix4;
address.prefixlen = p->prefixlen;
apply_mask_ipv4(&address);
+ nh.ifindex = ifc->ifp->ifindex;
+ nh.type = NEXTHOP_TYPE_IFINDEX;
+
/* Check if this interface is RIP enabled or not
or Check if this address's prefix is RIP enabled */
if ((rip_enable_if_lookup(ifc->ifp->name) >= 0)
|| (rip_enable_network_lookup2(ifc) >= 0))
rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
- &address, ifc->ifp->ifindex, NULL, 0, 0,
- 0);
+ &address, &nh, 0, 0, 0);
}
int rip_interface_address_add(int command, struct zclient *zclient,
@@ -879,6 +884,9 @@ static void rip_connect_set(struct interface *ifp, int set)
struct listnode *node, *nnode;
struct connected *connected;
struct prefix_ipv4 address;
+ struct nexthop nh;
+
+ memset(&nh, 0, sizeof(nh));
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
struct prefix *p;
@@ -892,6 +900,8 @@ static void rip_connect_set(struct interface *ifp, int set)
address.prefixlen = p->prefixlen;
apply_mask_ipv4(&address);
+ nh.ifindex = connected->ifp->ifindex;
+ nh.type = NEXTHOP_TYPE_IFINDEX;
if (set) {
/* Check once more wether this prefix is within a
* "network IF_OR_PREF" one */
@@ -900,7 +910,7 @@ static void rip_connect_set(struct interface *ifp, int set)
rip_redistribute_add(
ZEBRA_ROUTE_CONNECT,
RIP_ROUTE_INTERFACE, &address,
- connected->ifp->ifindex, NULL, 0, 0, 0);
+ &nh, 0, 0, 0);
} else {
rip_redistribute_delete(ZEBRA_ROUTE_CONNECT,
RIP_ROUTE_INTERFACE, &address,
@@ -909,7 +919,7 @@ static void rip_connect_set(struct interface *ifp, int set)
rip_redistribute_add(
ZEBRA_ROUTE_CONNECT,
RIP_ROUTE_REDISTRIBUTE, &address,
- connected->ifp->ifindex, NULL, 0, 0, 0);
+ &nh, 0, 0, 0);
}
}
}
diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c
index ad9f8cf80b..a37effa23c 100644
--- a/ripd/rip_routemap.c
+++ b/ripd/rip_routemap.c
@@ -129,7 +129,7 @@ static route_map_result_t route_match_interface(void *rule,
rinfo = object;
if (rinfo->ifindex_out == ifp->ifindex
- || rinfo->ifindex == ifp->ifindex)
+ || rinfo->nh.ifindex == ifp->ifindex)
return RMAP_MATCH;
else
return RMAP_NOMATCH;
@@ -171,7 +171,8 @@ static route_map_result_t route_match_ip_next_hop(void *rule,
rinfo = object;
p.family = AF_INET;
p.prefix =
- (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
+ (rinfo->nh.gate.ipv4.s_addr) ?
+ rinfo->nh.gate.ipv4 : rinfo->from;
p.prefixlen = IPV4_MAX_BITLEN;
alist = access_list_lookup(AFI_IP, (char *)rule);
@@ -217,7 +218,8 @@ route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
rinfo = object;
p.family = AF_INET;
p.prefix =
- (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
+ (rinfo->nh.gate.ipv4.s_addr) ?
+ rinfo->nh.gate.ipv4 : rinfo->from;
p.prefixlen = IPV4_MAX_BITLEN;
plist = prefix_list_lookup(AFI_IP, (char *)rule);
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 3772f6223e..041635e153 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -56,7 +56,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd)
if (count >= MULTIPATH_NUM)
break;
api_nh = &api.nexthops[count];
- api_nh->gate.ipv4 = rinfo->nexthop;
+ api_nh->gate = rinfo->nh.gate;
api_nh->type = NEXTHOP_TYPE_IPV4;
if (cmd == ZEBRA_ROUTE_ADD)
SET_FLAG(rinfo->flags, RIP_RTF_FIB);
@@ -121,8 +121,7 @@ static int rip_zebra_read_route(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct zapi_route api;
- struct in_addr nexthop;
- unsigned long ifindex;
+ struct nexthop nh;
if (!rip)
return 0;
@@ -130,19 +129,21 @@ static int rip_zebra_read_route(int command, struct zclient *zclient,
if (zapi_route_decode(zclient->ibuf, &api) < 0)
return -1;
- nexthop = api.nexthops[0].gate.ipv4;
- ifindex = api.nexthops[0].ifindex;
+ memset(&nh, 0, sizeof(nh));
+ nh.type = api.nexthops[0].type;
+ nh.gate.ipv4 = api.nexthops[0].gate.ipv4;
+ nh.ifindex = api.nexthops[0].ifindex;
/* Then fetch IPv4 prefixes. */
if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE,
- (struct prefix_ipv4 *)&api.prefix, ifindex,
- &nexthop, api.metric, api.distance,
+ (struct prefix_ipv4 *)&api.prefix, &nh,
+ api.metric, api.distance,
api.tag);
else if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL)
rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE,
(struct prefix_ipv4 *)&api.prefix,
- ifindex);
+ nh.ifindex);
return 0;
}
@@ -501,15 +502,19 @@ DEFUN (rip_default_information_originate,
"Distribute a default route\n")
{
struct prefix_ipv4 p;
+ struct nexthop nh;
if (!rip->default_information) {
memset(&p, 0, sizeof(struct prefix_ipv4));
+ memset(&nh, 0, sizeof(nh));
+
p.family = AF_INET;
+ nh.type = NEXTHOP_TYPE_IPV4;
rip->default_information = 1;
- rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
- NULL, 0, 0, 0);
+ rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p,
+ &nh, 0, 0, 0);
}
return CMD_SUCCESS;
@@ -585,7 +590,7 @@ static void rip_zebra_connected(struct zclient *zclient)
void rip_zclient_init(struct thread_master *master)
{
/* Set default value to the zebra client structure. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
zclient->zebra_connected = rip_zebra_connected;
zclient->interface_add = rip_interface_add;
diff --git a/ripd/ripd.c b/ripd/ripd.c
index aece5d03cd..b5cbc96bc3 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -424,9 +424,10 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
memset(&newinfo, 0, sizeof(newinfo));
newinfo.type = ZEBRA_ROUTE_RIP;
newinfo.sub_type = RIP_ROUTE_RTE;
- newinfo.nexthop = rte->nexthop;
+ newinfo.nh.gate.ipv4 = rte->nexthop;
newinfo.from = from->sin_addr;
- newinfo.ifindex = ifp->ifindex;
+ newinfo.nh.ifindex = ifp->ifindex;
+ newinfo.nh.type = NEXTHOP_TYPE_IPV4_IFINDEX;
newinfo.metric = rte->metric;
newinfo.metric_out = rte->metric; /* XXX */
newinfo.tag = ntohs(rte->tag); /* XXX */
@@ -488,7 +489,8 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
rp = route_node_get(rip->table, (struct prefix *)&p);
newinfo.rp = rp;
- newinfo.nexthop = *nexthop;
+ newinfo.nh.gate.ipv4 = *nexthop;
+ newinfo.nh.type = NEXTHOP_TYPE_IPV4;
newinfo.metric = rte->metric;
newinfo.tag = ntohs(rte->tag);
newinfo.distance = rip_distance_apply(&newinfo);
@@ -505,7 +507,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
break;
if (IPV4_ADDR_SAME(&rinfo->from, &from->sin_addr)
- && IPV4_ADDR_SAME(&rinfo->nexthop, nexthop))
+ && IPV4_ADDR_SAME(&rinfo->nh.gate.ipv4, nexthop))
break;
if (!listnextnode(node)) {
@@ -567,7 +569,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
/* Only routes directly connected to an interface
* (nexthop == 0)
* may have a valid NULL distance */
- if (rinfo->nexthop.s_addr != 0)
+ if (rinfo->nh.gate.ipv4.s_addr != 0)
old_dist = old_dist
? old_dist
: ZEBRA_RIP_DISTANCE_DEFAULT;
@@ -602,7 +604,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
If this datagram is from the same router as the existing
route, reinitialize the timeout. */
same = (IPV4_ADDR_SAME(&rinfo->from, &from->sin_addr)
- && (rinfo->ifindex == ifp->ifindex));
+ && (rinfo->nh.ifindex == ifp->ifindex));
old_dist = rinfo->distance ? rinfo->distance
: ZEBRA_RIP_DISTANCE_DEFAULT;
@@ -1461,7 +1463,7 @@ static int rip_send_packet(u_char *buf, int size, struct sockaddr_in *to,
/* Add redistributed route to RIP table. */
void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
- ifindex_t ifindex, struct in_addr *nexthop,
+ struct nexthop *nh,
unsigned int metric, unsigned char distance,
route_tag_t tag)
{
@@ -1480,15 +1482,13 @@ void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
memset(&newinfo, 0, sizeof(struct rip_info));
newinfo.type = type;
newinfo.sub_type = sub_type;
- newinfo.ifindex = ifindex;
newinfo.metric = 1;
newinfo.external_metric = metric;
newinfo.distance = distance;
if (tag <= UINT16_MAX) /* RIP only supports 16 bit tags */
newinfo.tag = tag;
newinfo.rp = rp;
- if (nexthop)
- newinfo.nexthop = *nexthop;
+ newinfo.nh = *nh;
if ((list = rp->info) != NULL && listcount(list) != 0) {
rinfo = listgetdata(listhead(list));
@@ -1512,23 +1512,15 @@ void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
}
}
- rinfo = rip_ecmp_replace(&newinfo);
+ (void)rip_ecmp_replace(&newinfo);
route_unlock_node(rp);
} else
- rinfo = rip_ecmp_add(&newinfo);
+ (void)rip_ecmp_add(&newinfo);
if (IS_RIP_DEBUG_EVENT) {
- if (!nexthop)
- zlog_debug(
- "Redistribute new prefix %s/%d on the interface %s",
- inet_ntoa(p->prefix), p->prefixlen,
- ifindex2ifname(ifindex, VRF_DEFAULT));
- else
- zlog_debug(
- "Redistribute new prefix %s/%d with nexthop %s on the interface %s",
- inet_ntoa(p->prefix), p->prefixlen,
- inet_ntoa(rinfo->nexthop),
- ifindex2ifname(ifindex, VRF_DEFAULT));
+ zlog_debug(
+ "Redistribute new prefix %s/%d",
+ inet_ntoa(p->prefix), p->prefixlen);
}
rip_event(RIP_TRIGGERED_UPDATE, 0);
@@ -1554,7 +1546,7 @@ void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p,
rinfo = listgetdata(listhead(list));
if (rinfo != NULL && rinfo->type == type
&& rinfo->sub_type == sub_type
- && rinfo->ifindex == ifindex) {
+ && rinfo->nh.ifindex == ifindex) {
/* Perform poisoned reverse. */
rinfo->metric = RIP_METRIC_INFINITY;
RIP_TIMER_ON(rinfo->t_garbage_collect,
@@ -1565,7 +1557,7 @@ void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p,
if (IS_RIP_DEBUG_EVENT)
zlog_debug(
- "Poisone %s/%d on the interface %s with an "
+ "Poison %s/%d on the interface %s with an "
"infinity metric [delete]",
inet_ntoa(p->prefix),
p->prefixlen,
@@ -2201,7 +2193,7 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
for (ALL_LIST_ELEMENTS_RO(list, listnode,
tmp_rinfo))
if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
- && tmp_rinfo->ifindex
+ && tmp_rinfo->nh.ifindex
== ifc->ifp->ifindex) {
suppress = 1;
break;
@@ -2233,8 +2225,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
* to avoid an IGP multi-level recursive look-up.
* see (4.4)
*/
- if (rinfo->ifindex == ifc->ifp->ifindex)
- rinfo->nexthop_out = rinfo->nexthop;
+ if (rinfo->nh.ifindex == ifc->ifp->ifindex)
+ rinfo->nexthop_out = rinfo->nh.gate.ipv4;
/* Interface route-map */
if (ri->routemap[RIP_FILTER_OUT]) {
@@ -2326,7 +2318,7 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
for (ALL_LIST_ELEMENTS_RO(list, listnode,
tmp_rinfo))
if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
- && tmp_rinfo->ifindex
+ && tmp_rinfo->nh.ifindex
== ifc->ifp->ifindex)
rinfo->metric_out =
RIP_METRIC_INFINITY;
@@ -2647,8 +2639,9 @@ void rip_redistribute_withdraw(int type)
"Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
inet_ntoa(p->prefix),
p->prefixlen,
- ifindex2ifname(rinfo->ifindex,
- VRF_DEFAULT));
+ ifindex2ifname(
+ rinfo->nh.ifindex,
+ VRF_DEFAULT));
}
rip_event(RIP_TRIGGERED_UPDATE, 0);
@@ -2861,9 +2854,13 @@ DEFUN (rip_route,
{
int idx_ipv4_prefixlen = 1;
int ret;
+ struct nexthop nh;
struct prefix_ipv4 p;
struct route_node *node;
+ memset(&nh, 0, sizeof(nh));
+ nh.type = NEXTHOP_TYPE_IPV4;
+
ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
if (ret < 0) {
vty_out(vty, "Malformed address\n");
@@ -2882,7 +2879,7 @@ DEFUN (rip_route,
node->info = (void *)1;
- rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0,
+ rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0,
0, 0);
return CMD_SUCCESS;
@@ -3454,14 +3451,30 @@ DEFUN (show_ip_rip,
if (len > 0)
vty_out(vty, "%*s", len, " ");
- if (rinfo->nexthop.s_addr)
+ switch(rinfo->nh.type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out(vty, "%-20s %2d ",
- inet_ntoa(rinfo->nexthop),
+ inet_ntoa(rinfo->nh.gate.ipv4),
rinfo->metric);
- else
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
vty_out(vty,
"0.0.0.0 %2d ",
rinfo->metric);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ vty_out(vty,
+ "blackhole %2d ",
+ rinfo->metric);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ vty_out(vty,
+ "V6 Address Hidden %2d ",
+ rinfo->metric);
+ break;
+ }
/* Route which exist in kernel routing table. */
if ((rinfo->type == ZEBRA_ROUTE_RIP)
diff --git a/ripd/ripd.h b/ripd/ripd.h
index ae34ed3f48..9a9c081bf9 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -23,6 +23,7 @@
#include "qobj.h"
#include "hook.h"
+#include "nexthop.h"
#include "rip_memory.h"
/* RIP version number. */
@@ -194,12 +195,9 @@ struct rip_info {
int sub_type;
/* RIP nexthop. */
- struct in_addr nexthop;
+ struct nexthop nh;
struct in_addr from;
- /* Which interface does this route come from. */
- ifindex_t ifindex;
-
/* Metric of this route. */
u_int32_t metric;
@@ -387,9 +385,11 @@ extern int rip_request_send(struct sockaddr_in *, struct interface *, u_char,
extern int rip_neighbor_lookup(struct sockaddr_in *);
extern int rip_redistribute_check(int);
-extern void rip_redistribute_add(int, int, struct prefix_ipv4 *, ifindex_t,
- struct in_addr *, unsigned int, unsigned char,
- route_tag_t);
+extern void rip_redistribute_add(int type, int sub_type,
+ struct prefix_ipv4 *p,
+ struct nexthop *nh,
+ unsigned int metric, unsigned char distance,
+ route_tag_t tag);
extern void rip_redistribute_delete(int, int, struct prefix_ipv4 *, ifindex_t);
extern void rip_redistribute_withdraw(int);
extern void rip_zebra_ipv4_add(struct route_node *);
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index 084d58ee53..18a8d14f09 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -413,7 +413,7 @@ static void ripng_zebra_connected(struct zclient *zclient)
void zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
zclient->zebra_connected = ripng_zebra_connected;
diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c
new file mode 100644
index 0000000000..1c80cf055a
--- /dev/null
+++ b/sharpd/sharp_main.c
@@ -0,0 +1,162 @@
+/*
+ * SHARP - main code
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include <lib/version.h>
+#include "getopt.h"
+#include "thread.h"
+#include "prefix.h"
+#include "linklist.h"
+#include "if.h"
+#include "vector.h"
+#include "vty.h"
+#include "command.h"
+#include "filter.h"
+#include "plist.h"
+#include "stream.h"
+#include "log.h"
+#include "memory.h"
+#include "privs.h"
+#include "sigevent.h"
+#include "zclient.h"
+#include "keychain.h"
+#include "distribute.h"
+#include "libfrr.h"
+#include "routemap.h"
+
+#include "sharp_zebra.h"
+#include "sharp_vty.h"
+
+uint32_t total_routes = 0;
+uint32_t installed_routes = 0;
+uint32_t removed_routes = 0;
+
+zebra_capabilities_t _caps_p[] = {
+ ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
+};
+
+struct zebra_privs_t sharp_privs = {
+#if defined(FRR_USER) && defined(FRR_GROUP)
+ .user = FRR_USER,
+ .group = FRR_GROUP,
+#endif
+#if defined(VTY_GROUP)
+ .vty_group = VTY_GROUP,
+#endif
+ .caps_p = _caps_p,
+ .cap_num_p = array_size(_caps_p),
+ .cap_num_i = 0};
+
+struct option longopts[] = {{0}};
+
+/* Master of threads. */
+struct thread_master *master;
+
+/* SIGHUP handler. */
+static void sighup(void)
+{
+ zlog_info("SIGHUP received");
+}
+
+/* SIGINT / SIGTERM handler. */
+static void sigint(void)
+{
+ zlog_notice("Terminating on signal");
+
+ exit(0);
+}
+
+/* SIGUSR1 handler. */
+static void sigusr1(void)
+{
+ zlog_rotate();
+}
+
+struct quagga_signal_t sharp_signals[] = {
+ {
+ .signal = SIGHUP,
+ .handler = &sighup,
+ },
+ {
+ .signal = SIGUSR1,
+ .handler = &sigusr1,
+ },
+ {
+ .signal = SIGINT,
+ .handler = &sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = &sigint,
+ },
+};
+
+#define SHARP_VTY_PORT 2614
+
+FRR_DAEMON_INFO(sharpd, SHARP, .vty_port = SHARP_VTY_PORT,
+
+ .proghelp = "Implementation of a Sharp of routes daemon.",
+
+ .signals = sharp_signals,
+ .n_signals = array_size(sharp_signals),
+
+ .privs = &sharp_privs, )
+
+extern void sharp_vty_init(void);
+
+int main(int argc, char **argv, char **envp)
+{
+ frr_preinit(&sharpd_di, argc, argv);
+ frr_opt_add("", longopts, "");
+
+ while (1) {
+ int opt;
+
+ opt = frr_getopt(argc, argv, NULL);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 0:
+ break;
+ default:
+ frr_help_exit(1);
+ break;
+ }
+ }
+
+ master = frr_init();
+
+ vrf_init(NULL, NULL, NULL, NULL);
+
+ sharp_zebra_init();
+
+ /* Get configuration file. */
+ sharp_vty_init();
+
+ frr_config_fork();
+ frr_run(master);
+
+ /* Not reached. */
+ return 0;
+}
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
new file mode 100644
index 0000000000..47bb37ce92
--- /dev/null
+++ b/sharpd/sharp_vty.c
@@ -0,0 +1,114 @@
+/*
+ * SHARP - vty code
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include "vty.h"
+#include "command.h"
+#include "prefix.h"
+#include "nexthop.h"
+#include "log.h"
+
+#include "sharpd/sharp_zebra.h"
+#include "sharpd/sharp_vty.h"
+#include "sharpd/sharp_vty_clippy.c"
+
+extern uint32_t total_routes;
+extern uint32_t installed_routes;
+extern uint32_t removed_routes;
+
+DEFPY (install_routes,
+ install_routes_cmd,
+ "install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes",
+ "install some routes\n"
+ "Routes to install\n"
+ "Address to start /32 generation at\n"
+ "Nexthop to use\n"
+ "Nexthop address\n"
+ "How many to create\n")
+{
+ int i;
+ struct prefix p;
+ struct nexthop nhop;
+ uint32_t temp;
+
+ total_routes = routes;
+ installed_routes = 0;
+
+ memset(&p, 0, sizeof(p));
+ memset(&nhop, 0, sizeof(nhop));
+
+ p.family = AF_INET;
+ p.prefixlen = 32;
+ p.u.prefix4 = start;
+
+ nhop.gate.ipv4 = nexthop;
+ nhop.type = NEXTHOP_TYPE_IPV4;
+
+ zlog_debug("Inserting %ld routes", routes);
+
+ temp = ntohl(p.u.prefix4.s_addr);
+ for (i = 0 ; i < routes ; i++) {
+ route_add(&p, &nhop);
+ p.u.prefix4.s_addr = htonl(++temp);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (remove_routes,
+ remove_routes_cmd,
+ "remove routes A.B.C.D$start (1-1000000)$routes",
+ "Remove some routes\n"
+ "Routes to remove\n"
+ "Starting spot\n"
+ "Routes to uniinstall\n")
+{
+ int i;
+ struct prefix p;
+ uint32_t temp;
+
+ total_routes = routes;
+ removed_routes = 0;
+
+ memset(&p, 0, sizeof(p));
+
+ p.family = AF_INET;
+ p.prefixlen = 32;
+ p.u.prefix4 = start;
+
+ zlog_debug("Removing %ld routes", routes);
+
+ temp = ntohl(p.u.prefix4.s_addr);
+ for (i = 0; i < routes ; i++) {
+ route_delete(&p);
+ p.u.prefix4.s_addr = htonl(++temp);
+ }
+
+ return CMD_SUCCESS;
+}
+
+void sharp_vty_init(void)
+{
+ install_element(ENABLE_NODE, &install_routes_cmd);
+ install_element(ENABLE_NODE, &remove_routes_cmd);
+ return;
+}
diff --git a/sharpd/sharp_vty.h b/sharpd/sharp_vty.h
new file mode 100644
index 0000000000..d4af095e89
--- /dev/null
+++ b/sharpd/sharp_vty.h
@@ -0,0 +1,26 @@
+/*
+ * VTY library for SHARP
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __SHARP_VTY_H__
+#define __SHARP_VTY_H__
+
+extern void sharp_vty_init(void);
+#endif
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
new file mode 100644
index 0000000000..4a5ae13c43
--- /dev/null
+++ b/sharpd/sharp_zebra.c
@@ -0,0 +1,208 @@
+/*
+ * Zebra connect code.
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include "thread.h"
+#include "command.h"
+#include "network.h"
+#include "prefix.h"
+#include "routemap.h"
+#include "table.h"
+#include "stream.h"
+#include "memory.h"
+#include "zclient.h"
+#include "filter.h"
+#include "plist.h"
+#include "log.h"
+#include "nexthop.h"
+
+#include "sharp_zebra.h"
+
+/* Zebra structure to hold current status. */
+struct zclient *zclient = NULL;
+
+/* For registering threads. */
+extern struct thread_master *master;
+
+static struct interface *zebra_interface_if_lookup(struct stream *s)
+{
+ char ifname_tmp[INTERFACE_NAMSIZ];
+
+ /* Read interface name. */
+ stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
+
+ /* And look it up. */
+ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
+}
+
+/* Inteface addition message from zebra. */
+static int interface_add(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+
+ ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
+
+ if (!ifp->info)
+ return 0;
+
+ return 0;
+}
+
+static int interface_delete(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s;
+
+ s = zclient->ibuf;
+ /* zebra_interface_state_read () updates interface structure in iflist
+ */
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (ifp == NULL)
+ return 0;
+
+ if_set_index(ifp, IFINDEX_INTERNAL);
+
+ return 0;
+}
+
+static int interface_address_add(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+
+ zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+
+ return 0;
+}
+
+static int interface_address_delete(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct connected *c;
+
+ c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+
+ if (!c)
+ return 0;
+
+ connected_free(c);
+ return 0;
+}
+
+static int interface_state_up(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+
+ zebra_interface_if_lookup(zclient->ibuf);
+
+ return 0;
+}
+
+static int interface_state_down(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+
+ zebra_interface_state_read(zclient->ibuf, vrf_id);
+
+ return 0;
+}
+
+extern uint32_t total_routes;
+extern uint32_t installed_routes;
+
+static int notify_owner(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct prefix p;
+ enum zapi_route_notify_owner note;
+
+ if (!zapi_route_notify_decode(zclient->ibuf, &p, &note))
+ return -1;
+
+ installed_routes++;
+
+ if (total_routes == installed_routes)
+ zlog_debug("Installed All Items");
+ return 0;
+}
+
+static void zebra_connected(struct zclient *zclient)
+{
+ zclient_send_reg_requests(zclient, VRF_DEFAULT);
+}
+
+void route_add(struct prefix *p, struct nexthop *nh)
+{
+ struct zapi_route api;
+ struct zapi_nexthop *api_nh;
+
+ memset(&api, 0, sizeof(api));
+ api.vrf_id = VRF_DEFAULT;
+ api.type = ZEBRA_ROUTE_SHARP;
+ api.safi = SAFI_UNICAST;
+ memcpy(&api.prefix, p, sizeof(*p));
+
+ SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
+
+ api_nh = &api.nexthops[0];
+ api_nh->gate.ipv4 = nh->gate.ipv4;
+ api_nh->type = nh->type;
+ api_nh->ifindex = nh->ifindex;
+ api.nexthop_num = 1;
+
+ zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+}
+
+void route_delete(struct prefix *p)
+{
+ struct zapi_route api;
+
+ memset(&api, 0, sizeof(api));
+ api.vrf_id = VRF_DEFAULT;
+ api.type = ZEBRA_ROUTE_SHARP;
+ api.safi = SAFI_UNICAST;
+ memcpy(&api.prefix, p, sizeof(*p));
+ zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+
+ return;
+}
+
+extern struct zebra_privs_t sharp_privs;
+
+void sharp_zebra_init(void)
+{
+ struct zclient_options opt = { .receive_notify = true };
+
+ zclient = zclient_new_notify(master, &opt);
+
+ zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
+ zclient->zebra_connected = zebra_connected;
+ zclient->interface_add = interface_add;
+ zclient->interface_delete = interface_delete;
+ zclient->interface_up = interface_state_up;
+ zclient->interface_down = interface_state_down;
+ zclient->interface_address_add = interface_address_add;
+ zclient->interface_address_delete = interface_address_delete;
+ zclient->notify_owner = notify_owner;
+}
diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h
new file mode 100644
index 0000000000..97100f61a6
--- /dev/null
+++ b/sharpd/sharp_zebra.h
@@ -0,0 +1,29 @@
+/*
+ * Zebra connect library for SHARP
+ * Copyright (C) Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __SHARP_ZEBRA_H__
+#define __SHARP_ZEBRA_H__
+
+extern void sharp_zebra_init(void);
+
+extern void route_add(struct prefix *p, struct nexthop *nh);
+extern void route_delete(struct prefix *p);
+#endif
diff --git a/sharpd/sharpd.conf.sample b/sharpd/sharpd.conf.sample
new file mode 100644
index 0000000000..bb1c2edca8
--- /dev/null
+++ b/sharpd/sharpd.conf.sample
@@ -0,0 +1,3 @@
+!
+!
+log stdout
diff --git a/sharpd/subdir.am b/sharpd/subdir.am
new file mode 100644
index 0000000000..da7d68e0bc
--- /dev/null
+++ b/sharpd/subdir.am
@@ -0,0 +1,21 @@
+#
+# sharpd
+#
+
+if SHARPD
+noinst_LIBRARIES += sharpd/libsharp.a
+sbin_PROGRAMS += sharpd/sharpd
+dist_examples_DATA += sharpd/sharpd.conf.sample
+endif
+
+sharpd_libsharp_a_SOURCES = \
+ sharpd/sharp_zebra.c \
+ sharpd/sharp_vty.c \
+ # end
+
+sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS)
+sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c
+
+sharpd_sharpd_SOURCES = sharpd/sharp_main.c
+sharpd_sharpd_LDADD = sharpd/libsharp.a lib/libfrr.la @LIBCAP@
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fafdd73bf3..2ee05fa935 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -17,6 +17,7 @@ if BGPD
TESTS_BGPD = \
bgpd/test_aspath \
bgpd/test_capability \
+ bgpd/test_packet \
bgpd/test_ecommunity \
bgpd/test_mp_attr \
bgpd/test_mpath
@@ -132,6 +133,7 @@ lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \
helpers/c/prng.c
bgpd_test_aspath_SOURCES = bgpd/test_aspath.c
bgpd_test_capability_SOURCES = bgpd/test_capability.c
+bgpd_test_packet_SOURCES = bgpd/test_packet.c
bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
@@ -167,6 +169,7 @@ lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD)
bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_packet_LDADD = $(BGP_TEST_LDADD)
bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index ccd3b6f4c2..247fcf7da0 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -374,7 +374,7 @@ static int global_test_init(void)
{
qobj_init();
master = thread_master_create(NULL);
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
bgp_master_init(master);
vrf_init(NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
diff --git a/tests/bgpd/test_packet.c b/tests/bgpd/test_packet.c
new file mode 100644
index 0000000000..298dd1e185
--- /dev/null
+++ b/tests/bgpd/test_packet.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 Cumulus Networks Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "qobj.h"
+#include "vty.h"
+#include "stream.h"
+#include "privs.h"
+#include "memory.h"
+#include "queue.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_open.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_packet.h"
+#include "bgpd/bgp_aspath.h"
+
+/* need these to link in libbgp */
+struct zebra_privs_t *bgpd_privs = NULL;
+struct thread_master *master = NULL;
+
+static struct bgp *bgp;
+static as_t asn = 100;
+
+extern int bgp_read_packet(struct peer *peer);
+
+/*
+ * This file is intended to be used as input for some sort of
+ * fuzzer. Specifically I had afl in mind when I wrote
+ * this code.
+ */
+int main(int argc, char *argv[])
+{
+ struct peer *peer;
+ int i, j;
+ struct thread t;
+
+ qobj_init();
+ bgp_attr_init();
+ master = thread_master_create(NULL);
+ bgp_master_init(master);
+ vrf_init(NULL, NULL, NULL, NULL);
+ bgp_option_set(BGP_OPT_NO_LISTEN);
+
+ if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
+ return -1;
+
+ peer = peer_create_accept(bgp);
+ peer->host = (char *)"foo";
+
+ for (i = AFI_IP; i < AFI_MAX; i++)
+ for (j = SAFI_UNICAST; j < SAFI_MAX; j++) {
+ peer->afc[i][j] = 1;
+ peer->afc_adv[i][j] = 1;
+ }
+
+ SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
+ peer->status = Established;
+
+ peer->fd = open(argv[1], O_RDONLY|O_NONBLOCK);
+ t.arg = peer;
+ peer->t_read = &t;
+
+ printf("bgp_read_packet returns: %d\n", bgp_read(&t));
+}
diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c
index 5e604db61a..b08f63b70f 100644
--- a/tests/test_lblmgr.c
+++ b/tests/test_lblmgr.c
@@ -115,7 +115,7 @@ void init_zclient(struct thread_master *master, char *lm_zserv_path)
{
frr_zclient_addr(&zclient_addr, &zclient_addr_len, lm_zserv_path);
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
/* zclient_init(zclient, ZEBRA_LABEL_MANAGER, 0); */
zclient->sock = -1;
zclient->redist_default = ZEBRA_ROUTE_LDP;
diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons
index a460827924..ac17fed03a 100644
--- a/tools/etc/frr/daemons
+++ b/tools/etc/frr/daemons
@@ -33,3 +33,4 @@ ldpd=no
nhrpd=no
eigrpd=no
babeld=no
+sharpd=no
diff --git a/tools/etc/frr/daemons.conf b/tools/etc/frr/daemons.conf
index 0d92d13671..3f40836c90 100644
--- a/tools/etc/frr/daemons.conf
+++ b/tools/etc/frr/daemons.conf
@@ -16,6 +16,7 @@ ldpd_options=" --daemon -A 127.0.0.1"
nhrpd_options=" --daemon -A 127.0.0.1"
eigrpd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
+sharpd_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf
index 2d3b884e7e..b8d4c1c03b 100644
--- a/tools/etc/iproute2/rt_protos.d/frr.conf
+++ b/tools/etc/iproute2/rt_protos.d/frr.conf
@@ -8,3 +8,4 @@
191 nhrp
192 eigrp
193 ldp
+194 sharp \ No newline at end of file
diff --git a/tools/frr b/tools/frr
index 78190aadb0..0f6140d3ec 100755
--- a/tools/frr
+++ b/tools/frr
@@ -21,7 +21,7 @@ V_PATH=/var/run/frr
# Local Daemon selection may be done by using /etc/frr/daemons.
# See /usr/share/doc/frr/README.Debian.gz for further information.
# Keep zebra first and do not list watchfrr!
-DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd"
+DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd"
MAX_INSTANCES=5
RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py
diff --git a/tools/frr.service b/tools/frr.service
index 51dbbe2f32..4301ec9dc7 100644
--- a/tools/frr.service
+++ b/tools/frr.service
@@ -1,6 +1,6 @@
[Unit]
-Description=Cumulus Linux FRR
-After=syslog.target networking.service
+Description=FRRouting
+After=networking.service
OnFailure=heartbeat-failed@%n.service
[Service]
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
index 5156d336b3..3ddb6aba54 100644
--- a/vtysh/Makefile.am
+++ b/vtysh/Makefile.am
@@ -132,6 +132,10 @@ vtysh_scan += $(top_srcdir)/babeld/babel_zebra.c
vtysh_scan += $(top_srcdir)/babeld/babeld.c
endif
+if SHARPD
+vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c
+endif
+
if SNMP
vtysh_scan += $(top_srcdir)/lib/agentx.c
endif
diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index f33c7b9603..dedf3d1647 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -82,7 +82,7 @@ foreach (@ARGV) {
$protocol = "VTYSH_RIPD";
}
elsif ($file =~ /lib\/routemap\.c$/) {
- $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD";
+ $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD";
}
elsif ($file =~ /lib\/vrf\.c$/) {
$protocol = "VTYSH_ALL";
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index b021607240..76343ded60 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -74,6 +74,7 @@ struct vtysh_client vtysh_client[] = {
{.fd = -1, .name = "nhrpd", .flag = VTYSH_NHRPD, .next = NULL},
{.fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL},
{.fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .next = NULL},
+ {.fd = -1, .name = "sharpd", .flag = VTYSH_SHARPD, .next = NULL},
{.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL},
};
@@ -1045,7 +1046,9 @@ struct cmd_node link_params_node = {
LINK_PARAMS_NODE, "%s(config-link-params)# ",
};
+#if defined(HAVE_RPKI)
static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1};
+#endif
/* Defined in lib/vty.c */
extern struct cmd_node vty_node;
@@ -1183,6 +1186,7 @@ DEFUNSH(VTYSH_BGPD, address_family_ipv6_labeled_unicast,
return CMD_SUCCESS;
}
+#if defined(HAVE_RPKI)
DEFUNSH(VTYSH_BGPD,
rpki,
rpki_cmd,
@@ -1211,6 +1215,7 @@ DEFUNSH(VTYSH_BGPD,
{
return rpki_exit(self, vty, argc, argv);
}
+#endif
DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
"address-family <l2vpn evpn>",
@@ -3010,7 +3015,9 @@ void vtysh_init_vty(void)
install_node(&keychain_key_node, NULL);
install_node(&isis_node, NULL);
install_node(&vty_node, NULL);
+#if defined(HAVE_RPKI)
install_node(&rpki_node, NULL);
+#endif
struct cmd_node *node;
for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
@@ -3209,10 +3216,12 @@ void vtysh_init_vty(void)
install_element(BGP_EVPN_NODE, &exit_address_family_cmd);
install_element(BGP_IPV6L_NODE, &exit_address_family_cmd);
+#if defined(HAVE_RPKI)
install_element(CONFIG_NODE, &rpki_cmd);
install_element(RPKI_NODE, &rpki_exit_cmd);
install_element(RPKI_NODE, &rpki_quit_cmd);
install_element(RPKI_NODE, &vtysh_end_all_cmd);
+#endif
/* EVPN commands */
install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd);
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 9d6ea4bda4..c584d7a905 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -37,13 +37,15 @@ DECLARE_MGROUP(MVTYSH)
#define VTYSH_NHRPD 0x800
#define VTYSH_EIGRPD 0x1000
#define VTYSH_BABELD 0x2000
+#define VTYSH_SHARPD 0x4000
+
/* commands in REALLYALL are crucial to correct vtysh operation */
#define VTYSH_REALLYALL ~0U
/* watchfrr is not in ALL since library CLI functions should not be
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
-#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD
+#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD|VTYSH_EIGRPD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD
#define VTYSH_NS VTYSH_ZEBRA
diff --git a/zebra/client_main.c b/zebra/client_main.c
index 95b9d00dc0..9b82e48261 100644
--- a/zebra/client_main.c
+++ b/zebra/client_main.c
@@ -184,7 +184,7 @@ int main(int argc, char **argv)
master = thread_master_create(NULL);
/* Establish connection to zebra. */
- zclient = zclient_new(master);
+ zclient = zclient_new_notify(master, &zclient_options_default);
zclient->enable = 1;
zclient_socket_connect(zclient);
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index 6fbb751789..bf4522b70f 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -221,7 +221,7 @@ static void lm_zclient_init(char *lm_zserv_path)
lm_zserv_path);
/* Set default values. */
- zclient = zclient_new(zebrad.master);
+ zclient = zclient_new_notify(zebrad.master, &zclient_options_default);
zclient->sock = -1;
zclient->t_connect = NULL;
lm_zclient_connect(NULL);
diff --git a/zebra/main.c b/zebra/main.c
index cf677a7753..36c931c4ee 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -201,6 +201,9 @@ int main(int argc, char **argv)
char *lblmgr_path = NULL;
struct sockaddr_storage dummy;
socklen_t dummylen;
+#if defined(HANDLE_ZAPI_FUZZING)
+ char *fuzzing = NULL;
+#endif
frr_preinit(&zebra_di, argc, argv);
@@ -209,6 +212,9 @@ int main(int argc, char **argv)
#ifdef HAVE_NETLINK
"s:"
#endif
+#if defined(HANDLE_ZAPI_FUZZING)
+ "c:"
+#endif
,
longopts,
" -b, --batch Runs in batch mode\n"
@@ -221,6 +227,9 @@ int main(int argc, char **argv)
#ifdef HAVE_NETLINK
" -s, --nl-bufsize Set netlink receive buffer size\n"
#endif /* HAVE_NETLINK */
+#if defined(HANDLE_ZAPI_FUZZING)
+ " -c <file> Bypass normal startup use this file for tetsting of zapi"
+#endif
);
while (1) {
@@ -271,6 +280,11 @@ int main(int argc, char **argv)
nl_rcvbufsize = atoi(optarg);
break;
#endif /* HAVE_NETLINK */
+#if defined(HANDLE_ZAPI_FUZZING)
+ case 'c':
+ fuzzing = optarg;
+ break;
+#endif
default:
frr_help_exit(1);
break;
@@ -308,6 +322,13 @@ int main(int argc, char **argv)
* routing socket. */
zebra_ns_init();
+#if defined(HANDLE_ZAPI_FUZZING)
+ if (fuzzing) {
+ zserv_read_file(fuzzing);
+ exit(0);
+ }
+#endif
+
/* 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
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index e8333ef0cf..3830e1fbde 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -98,7 +98,7 @@ static inline int is_selfroute(int proto)
|| (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)
|| (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP)
|| (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)
- || (proto == RTPROT_RIP)) {
+ || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)) {
return 1;
}
@@ -139,6 +139,9 @@ static inline int zebra2proto(int proto)
case ZEBRA_ROUTE_LDP:
proto = RTPROT_LDP;
break;
+ case ZEBRA_ROUTE_SHARP:
+ proto = RTPROT_SHARP;
+ break;
default:
proto = RTPROT_ZEBRA;
break;
@@ -1605,7 +1608,23 @@ int kernel_route_rib(struct prefix *p, struct prefix *src_p,
if (old && !new)
return netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
- return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 1);
+ if (p->family == AF_INET)
+ return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 1);
+
+ /*
+ * So v6 route replace semantics are not in the kernel at this
+ * point as I understand it.
+ * So let's do a delete than an add.
+ * In the future once v6 route replace semantics are in
+ * we can figure out what to do here to allow working
+ * with old and new kernels.
+ *
+ * I'm also intentionally ignoring the failure case
+ * of the route delete. If that happens yeah we're
+ * screwed.
+ */
+ netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
+ return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 0);
}
int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla,
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index afb03f878d..51350fd6fb 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -51,6 +51,7 @@
#define RTPROT_NHRP 191
#define RTPROT_EIGRP 192
#define RTPROT_LDP 193
+#define RTPROT_SHARP 194
void rt_netlink_init(void);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b5c2bc6dae..791f319120 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -449,9 +449,15 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
while (rn) {
route_unlock_node(rn);
- /* If lookup self prefix return immediately. */
- if (rn == top)
- return 0;
+ /* Lookup should halt if we've matched against ourselves ('top',
+ * if specified) - i.e., we cannot have a nexthop NH1 is
+ * resolved by a route NH1. The exception is if the route is a
+ * host route.
+ */
+ if (top && rn == top)
+ if (((afi == AFI_IP) && (rn->p.prefixlen != 32)) ||
+ ((afi == AFI_IP6) && (rn->p.prefixlen != 128)))
+ return 0;
/* Pick up selected route. */
/* However, do not resolve over default route unless explicitly
@@ -1022,6 +1028,14 @@ int rib_install_kernel(struct route_node *rn, struct route_entry *re,
}
}
+ /*
+ * If this is a replace to a new RE let the originator of the RE
+ * know that they've lost
+ */
+ if (old && old != re)
+ zsend_route_notify_owner(old->type, old->instance,
+ old->vrf_id, p,
+ ZAPI_ROUTE_BETTER_ADMIN_WON);
/*
* Make sure we update the FPM any time we send new information to
@@ -1042,7 +1056,11 @@ int rib_install_kernel(struct route_node *rn, struct route_entry *re,
else
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
}
- }
+ zsend_route_notify_owner(re->type, re->instance, re->vrf_id,
+ p, ZAPI_ROUTE_INSTALLED);
+ } else
+ zsend_route_notify_owner(re->type, re->instance, re->vrf_id,
+ p, ZAPI_ROUTE_FAIL_INSTALL);
return ret;
}
@@ -1060,7 +1078,7 @@ int rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
if (info->safi != SAFI_UNICAST) {
for (ALL_NEXTHOPS(re->nexthop, nexthop))
- SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
return ret;
}
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 355fef94f4..33d0b3a641 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -370,11 +370,12 @@ static int zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
}
/*
- * Determine appropriate route (RE entry) resolving a tracked entry
- * (nexthop or BGP route for import).
+ * Determine appropriate route (RE entry) resolving a tracked BGP route
+ * for BGP route for import.
*/
-static struct route_entry *zebra_rnh_resolve_entry(vrf_id_t vrfid, int family,
- rnh_type_t type,
+static
+struct route_entry *zebra_rnh_resolve_import_entry(vrf_id_t vrfid,
+ int family,
struct route_node *nrn,
struct rnh *rnh,
struct route_node **prn)
@@ -393,48 +394,21 @@ static struct route_entry *zebra_rnh_resolve_entry(vrf_id_t vrfid, int family,
if (!rn)
return NULL;
- /* When resolving nexthops, do not resolve via the default route unless
- * 'ip nht resolve-via-default' is configured.
- */
- if ((type == RNH_NEXTHOP_TYPE)
- && (is_default_prefix(&rn->p)
- && !nh_resolve_via_default(rn->p.family)))
- re = NULL;
- else if ((type == RNH_IMPORT_CHECK_TYPE)
- && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)
- && !prefix_same(&nrn->p, &rn->p))
- re = NULL;
- else {
- /* Identify appropriate route entry. */
- RNODE_FOREACH_RE (rn, re) {
- if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
- continue;
- if (!CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
- continue;
+ /* Unlock route node - we don't need to lock when walking the tree. */
+ route_unlock_node(rn);
- if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
- if (re->type == ZEBRA_ROUTE_CONNECT)
- break;
- if (re->type == ZEBRA_ROUTE_NHRP) {
- struct nexthop *nexthop;
- for (nexthop = re->nexthop; nexthop;
- nexthop = nexthop->next)
- if (nexthop->type
- == NEXTHOP_TYPE_IFINDEX)
- break;
- if (nexthop)
- break;
- }
- } else if ((type == RNH_IMPORT_CHECK_TYPE)
- && (re->type == ZEBRA_ROUTE_BGP))
- continue;
- else
- break;
- }
+ if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH) &&
+ !prefix_same(&nrn->p, &rn->p))
+ return NULL;
+
+ /* Identify appropriate route entry. */
+ RNODE_FOREACH_RE(rn, re) {
+ if (!CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED) &&
+ CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED) &&
+ (re->type != ZEBRA_ROUTE_BGP))
+ break;
}
- /* Need to unlock route node */
- route_unlock_node(rn);
if (re)
*prn = rn;
return re;
@@ -650,6 +624,86 @@ static void zebra_rnh_process_static_routes(vrf_id_t vrfid, int family,
}
}
+/*
+ * Determine appropriate route (route entry) resolving a tracked
+ * nexthop.
+ */
+static struct route_entry *zebra_rnh_resolve_nexthop_entry(vrf_id_t vrfid,
+ int family,
+ struct route_node *nrn,
+ struct rnh *rnh,
+ struct route_node **prn)
+{
+ struct route_table *route_table;
+ struct route_node *rn;
+ struct route_entry *re;
+
+ *prn = NULL;
+
+ route_table = zebra_vrf_table(family2afi(family), SAFI_UNICAST, vrfid);
+ if (!route_table)
+ return NULL;
+
+ rn = route_node_match(route_table, &nrn->p);
+ if (!rn)
+ return NULL;
+
+ /* Unlock route node - we don't need to lock when walking the tree. */
+ route_unlock_node(rn);
+
+ /* While resolving nexthops, we may need to walk up the tree from the
+ * most-specific match. Do similar logic as in zebra_rib.c
+ */
+ while (rn) {
+ /* Do not resolve over default route unless allowed &&
+ * match route to be exact if so specified
+ */
+ if (is_default_prefix(&rn->p) &&
+ !nh_resolve_via_default(rn->p.family))
+ return NULL;
+
+ /* Identify appropriate route entry. */
+ RNODE_FOREACH_RE(rn, re) {
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+ continue;
+ if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+ continue;
+
+ if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
+ if ((re->type == ZEBRA_ROUTE_CONNECT)
+ || (re->type == ZEBRA_ROUTE_STATIC))
+ break;
+ if (re->type == ZEBRA_ROUTE_NHRP) {
+ struct nexthop *nexthop;
+
+ for (nexthop = re->nexthop;
+ nexthop;
+ nexthop = nexthop->next)
+ if (nexthop->type
+ == NEXTHOP_TYPE_IFINDEX)
+ break;
+ if (nexthop)
+ break;
+ }
+ } else
+ break;
+ }
+
+ /* Route entry found, we're done; else, walk up the tree. */
+ if (re) {
+ *prn = rn;
+ return re;
+ }
+
+ if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
+ rn = rn->parent;
+ else
+ return NULL;
+ }
+
+ return NULL;
+}
+
static void zebra_rnh_process_pseudowires(vrf_id_t vrfid, struct rnh *rnh)
{
struct zebra_pw *pw;
@@ -724,7 +778,12 @@ static void zebra_rnh_evaluate_entry(vrf_id_t vrfid, int family, int force,
rnh = nrn->info;
/* Identify route entry (RE) resolving this tracked entry. */
- re = zebra_rnh_resolve_entry(vrfid, family, type, nrn, rnh, &prn);
+ if (type == RNH_IMPORT_CHECK_TYPE)
+ re = zebra_rnh_resolve_import_entry(vrfid, family, nrn,
+ rnh, &prn);
+ else
+ re = zebra_rnh_resolve_nexthop_entry(vrfid, family, nrn, rnh,
+ &prn);
/* If the entry cannot be resolved and that is also the existing state,
* there is nothing further to do.
@@ -759,7 +818,13 @@ static void zebra_rnh_clear_nhc_flag(vrf_id_t vrfid, int family,
rnh = nrn->info;
- re = zebra_rnh_resolve_entry(vrfid, family, type, nrn, rnh, &prn);
+ /* Identify route entry (RIB) resolving this tracked entry. */
+ if (type == RNH_IMPORT_CHECK_TYPE)
+ re = zebra_rnh_resolve_import_entry(vrfid, family, nrn,
+ rnh, &prn);
+ else
+ re = zebra_rnh_resolve_nexthop_entry(vrfid, family, nrn, rnh,
+ &prn);
if (re) {
UNSET_FLAG(re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 73f0717124..43895378cd 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -43,7 +43,9 @@
#include "zebra/zebra_static.h"
#include "lib/json.h"
#include "zebra/zebra_vxlan.h"
+#ifndef VTYSH_EXTRACT_PL
#include "zebra/zebra_vty_clippy.c"
+#endif
#include "zebra/zserv.h"
extern int allow_delete;
@@ -311,7 +313,7 @@ DEFUN (show_ip_rpf,
{
int uj = use_json(argc, argv);
return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
- false, uj, 0, NULL, false, -1, 0);
+ false, uj, 0, NULL, false, 0, 0);
}
DEFUN (show_ip_rpf_addr,
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index f5caf9d0b9..9c70b55a1a 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -759,7 +759,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni,
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
- client = zebra_find_client(ZEBRA_ROUTE_BGP);
+ client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
/* BGP may not be running. */
if (!client)
return 0;
@@ -2122,7 +2122,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
struct zserv *client;
struct stream *s;
- client = zebra_find_client(ZEBRA_ROUTE_BGP);
+ client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
/* BGP may not be running. */
if (!client)
return 0;
@@ -2154,7 +2154,7 @@ static int zvni_send_del_to_client(vni_t vni)
struct zserv *client;
struct stream *s;
- client = zebra_find_client(ZEBRA_ROUTE_BGP);
+ client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
/* BGP may not be running. */
if (!client)
return 0;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 9d9a7cd783..b6d70084c0 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -988,6 +988,43 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
return zebra_server_send_message(client);
}
+int zsend_route_notify_owner(u_char proto, u_short instance,
+ vrf_id_t vrf_id, struct prefix *p,
+ enum zapi_route_notify_owner note)
+{
+ struct zserv *client;
+ struct stream *s;
+ uint8_t blen;
+
+ client = zebra_find_client(proto, instance);
+ if (!client || !client->notify_owner) {
+ if (IS_ZEBRA_DEBUG_PACKET) {
+ char buff[PREFIX_STRLEN];
+
+ zlog_debug("Not Notifying Owner: %u about prefix %s",
+ proto, prefix2str(p, buff, sizeof(buff)));
+ }
+ return 0;
+ }
+
+ s = client->obuf;
+ stream_reset(s);
+
+ zserv_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
+
+ stream_put(s, &note, sizeof(note));
+
+ stream_putc(s, p->family);
+
+ blen = prefix_blen(p);
+ stream_putc(s, p->prefixlen);
+ stream_put(s, &p->u.prefix, blen);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zebra_server_send_message(client);
+}
+
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int zsend_router_id_update(struct zserv *client, struct prefix *p,
vrf_id_t vrf_id)
@@ -1884,9 +1921,13 @@ static void zread_hello(struct zserv *client)
/* type of protocol (lib/zebra.h) */
u_char proto;
u_short instance;
+ u_char notify;
STREAM_GETC(client->ibuf, proto);
STREAM_GETW(client->ibuf, instance);
+ STREAM_GETC(client->ibuf, notify);
+ if (notify)
+ client->notify_owner = true;
/* accept only dynamic routing protocols */
if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) {
@@ -2562,6 +2603,26 @@ static inline void zserv_handle_commands(struct zserv *client,
}
}
+#if defined(HANDLE_ZAPI_FUZZING)
+static void zserv_write_incoming(struct stream *orig, uint16_t command)
+{
+ char fname[MAXPATHLEN];
+ struct stream *copy;
+ int fd = -1;
+
+ copy = stream_dup(orig);
+ stream_set_getp(copy, 0);
+
+ zserv_privs.change(ZPRIVS_RAISE);
+ snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
+ fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+ stream_flush(copy, fd);
+ close(fd);
+ zserv_privs.change(ZPRIVS_LOWER);
+ stream_free(copy);
+}
+#endif
+
/* Handler of zebra service request. */
static int zebra_client_read(struct thread *thread)
{
@@ -2572,7 +2633,11 @@ static int zebra_client_read(struct thread *thread)
uint8_t marker, version;
vrf_id_t vrf_id;
struct zebra_vrf *zvrf;
+#if defined(HANDLE_ZAPI_FUZZING)
+ int packets = 1;
+#else
int packets = zebrad.packets_to_process;
+#endif
/* Get thread data. Reset reading thread because I'm running. */
sock = THREAD_FD(thread);
@@ -2662,6 +2727,9 @@ static int zebra_client_read(struct thread *thread)
}
}
+#if defined(HANDLE_ZAPI_FUZZING)
+ zserv_write_incoming(client->ibuf, command);
+#endif
length -= ZEBRA_HEADER_SIZE;
/* Debug packet information. */
@@ -2935,13 +3003,14 @@ static void zebra_show_client_brief(struct vty *vty, struct zserv *client)
client->v6_route_del_cnt);
}
-struct zserv *zebra_find_client(u_char proto)
+struct zserv *zebra_find_client(u_char proto, u_short instance)
{
struct listnode *node, *nnode;
struct zserv *client;
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
- if (client->proto == proto)
+ if (client->proto == proto &&
+ client->instance == instance)
return client;
}
@@ -3209,6 +3278,26 @@ static struct cmd_node forwarding_node = {FORWARDING_NODE,
"", /* This node has no interface. */
1};
+#if defined(HANDLE_ZAPI_FUZZING)
+void zserv_read_file(char *input)
+{
+ int fd;
+ struct zserv *client = NULL;
+ struct thread t;
+
+ zebra_client_create(-1);
+ client = zebrad.client_list->head->data;
+ t.arg = client;
+
+ fd = open(input, O_RDONLY|O_NONBLOCK);
+ t.u.fd = fd;
+
+ zebra_client_read(&t);
+
+ close(fd);
+}
+#endif
+
/* Initialisation of zebra and installation of commands. */
void zebra_init(void)
{
diff --git a/zebra/zserv.h b/zebra/zserv.h
index 279b56ec3c..6077dc105a 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -75,6 +75,8 @@ struct zserv {
/* Router-id information. */
vrf_bitmap_t ridinfo;
+ bool notify_owner;
+
/* client's protocol */
u_char proto;
u_short instance;
@@ -183,6 +185,10 @@ extern int zsend_interface_vrf_update(struct zserv *, struct interface *,
extern int zsend_interface_link_params(struct zserv *, struct interface *);
extern int zsend_pw_update(struct zserv *, struct zebra_pw *);
+extern int zsend_route_notify_owner(u_char proto, u_short instance,
+ vrf_id_t vrf_id, struct prefix *p,
+ enum zapi_route_notify_owner note);
+
extern pid_t pid;
extern void zserv_create_header(struct stream *s, uint16_t cmd,
@@ -191,6 +197,10 @@ extern void zserv_nexthop_num_warn(const char *, const struct prefix *,
const unsigned int);
extern int zebra_server_send_message(struct zserv *client);
-extern struct zserv *zebra_find_client(u_char proto);
+extern struct zserv *zebra_find_client(u_char proto, u_short instance);
+
+#if defined(HANDLE_ZAPI_FUZZING)
+extern void zserv_read_file(char *input);
+#endif
#endif /* _ZEBRA_ZEBRA_H */