diff options
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, ¬e)) + 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 */ @@ -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, ¬e)) + 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 @@ -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, ¬e, 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 */ |
