summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dir-locals.el8
-rw-r--r--bgpd/bgp_debug.c14
-rw-r--r--bgpd/bgp_route.c7
-rw-r--r--bgpd/bgp_vty.c42
-rw-r--r--bgpd/bgp_zebra.c2
-rw-r--r--bgpd/bgpd.c7
-rw-r--r--bgpd/bgpd.h6
-rw-r--r--bgpd/rfapi/rfapi_import.c4
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c12
-rw-r--r--debian/copyright5
-rw-r--r--doc/developer/workflow.rst28
-rw-r--r--doc/user/bgp.rst8
-rw-r--r--eigrpd/eigrp_network.c3
-rw-r--r--eigrpd/eigrp_topology.c2
-rw-r--r--eigrpd/eigrp_zebra.c2
-rw-r--r--isisd/isis_circuit.c10
-rw-r--r--isisd/isis_zebra.c2
-rw-r--r--ldpd/ldp_zebra.c2
-rw-r--r--lib/if.c58
-rw-r--r--lib/if.h4
-rw-r--r--lib/prefix.c20
-rw-r--r--lib/prefix.h10
-rw-r--r--nhrpd/nhrp_interface.c2
-rw-r--r--ospf6d/ospf6_zebra.c2
-rw-r--r--ospfd/ospf_bfd.c26
-rw-r--r--ospfd/ospf_interface.c3
-rw-r--r--ospfd/ospf_zebra.c4
-rw-r--r--pbrd/pbr_vty.c12
-rw-r--r--pbrd/pbr_zebra.c2
-rw-r--r--pimd/pim_ifchannel.c12
-rw-r--r--pimd/pim_neighbor.c2
-rw-r--r--pimd/pim_tlv.c3
-rw-r--r--pimd/pim_zebra.c2
-rw-r--r--ripd/rip_interface.c2
-rw-r--r--ripngd/ripng_interface.c2
-rw-r--r--sharpd/sharp_zebra.c2
-rw-r--r--staticd/static_zebra.c4
-rwxr-xr-xtools/tarsource.sh9
-rw-r--r--zebra/connected.c4
-rw-r--r--zebra/interface.c10
40 files changed, 243 insertions, 116 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 21392ecf28..e47f245db7 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -2,7 +2,7 @@
;;; For more information see (info "(emacs) Directory Variables")
;;; Match project coding conventions
-((c-mode
- (indent-tabs-mode . t)
- (show-trailing-whitespace . t)
- (c-basic-offset . 8)))
+((c-mode . ((indent-tabs-mode . t)
+ (show-trailing-whitespace . t)
+ (c-basic-offset . 8)
+ )))
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index f476b16188..0e4c3a3e12 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -209,7 +209,7 @@ static void bgp_debug_list_free(struct list *list)
listnode_delete(list, filter);
if (filter->p)
- prefix_free(filter->p);
+ prefix_free(&filter->p);
if (filter->host)
XFREE(MTYPE_BGP_DEBUG_STR, filter->host);
@@ -323,7 +323,7 @@ static int bgp_debug_list_remove_entry(struct list *list, const char *host,
} else if (p && filter->p->prefixlen == p->prefixlen
&& prefix_match(filter->p, p)) {
listnode_delete(list, filter);
- prefix_free(filter->p);
+ prefix_free(&filter->p);
XFREE(MTYPE_BGP_DEBUG_FILTER, filter);
return 1;
}
@@ -1412,7 +1412,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
ret = bgp_debug_parse_evpn_prefix(vty, argv, argc, &argv_p);
if (ret != CMD_SUCCESS) {
- prefix_free(argv_p);
+ prefix_free(&argv_p);
return ret;
}
@@ -1425,7 +1425,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
vty_out(vty,
"BGP updates debugging is already enabled for %s\n",
buf);
- prefix_free(argv_p);
+ prefix_free(&argv_p);
return CMD_SUCCESS;
}
@@ -1438,7 +1438,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
vty_out(vty, "BGP updates debugging is on for %s\n", buf);
}
- prefix_free(argv_p);
+ prefix_free(&argv_p);
return CMD_SUCCESS;
}
@@ -1477,7 +1477,7 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi,
ret = bgp_debug_parse_evpn_prefix(vty, argv, argc, &argv_p);
if (ret != CMD_SUCCESS) {
- prefix_free(argv_p);
+ prefix_free(&argv_p);
return ret;
}
@@ -1505,7 +1505,7 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi,
vty_out(vty, "BGP updates debugging was not enabled for %s\n",
buf);
- prefix_free(argv_p);
+ prefix_free(&argv_p);
return ret;
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 77428bbb0f..c07fa2516e 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1639,9 +1639,9 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
return 0;
}
-#ifdef BGP_SEND_ASPATH_CHECK
/* AS path loop check. */
- if (onlypeer && aspath_loop_check(piattr->aspath, onlypeer->as)) {
+ if (onlypeer && onlypeer->as_path_loop_detection
+ && aspath_loop_check(piattr->aspath, onlypeer->as)) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
zlog_debug(
"%s [Update:SEND] suppress announcement to peer AS %u "
@@ -1649,7 +1649,6 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
onlypeer->host, onlypeer->as);
return 0;
}
-#endif /* BGP_SEND_ASPATH_CHECK */
/* If we're a CONFED we need to loop check the CONFED ID too */
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
@@ -10549,7 +10548,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
}
ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
- prefix_free(p);
+ prefix_free(&p);
return ret;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9e81831ac7..17c93ffc38 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -6381,6 +6381,44 @@ ALIAS_HIDDEN(no_neighbor_addpath_tx_bestpath_per_as,
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Use addpath to advertise the bestpath per each neighboring AS\n")
+DEFPY(
+ neighbor_aspath_loop_detection, neighbor_aspath_loop_detection_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor sender-as-path-loop-detection",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Detect AS loops before sending to neighbor\n")
+{
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty(vty, neighbor);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ peer->as_path_loop_detection = true;
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(
+ no_neighbor_aspath_loop_detection,
+ no_neighbor_aspath_loop_detection_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor sender-as-path-loop-detection",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Detect AS loops before sending to neighbor\n")
+{
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty(vty, neighbor);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ peer->as_path_loop_detection = false;
+
+ return CMD_SUCCESS;
+}
+
static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
struct ecommunity **list)
{
@@ -13678,6 +13716,10 @@ void bgp_vty_init(void)
install_element(BGP_VPNV6_NODE,
&no_neighbor_addpath_tx_bestpath_per_as_cmd);
+ /* "neighbor sender-as-path-loop-detection" commands. */
+ install_element(BGP_NODE, &neighbor_aspath_loop_detection_cmd);
+ install_element(BGP_NODE, &no_neighbor_aspath_loop_detection_cmd);
+
/* "neighbor passive" commands. */
install_element(BGP_NODE, &neighbor_passive_cmd);
install_element(BGP_NODE, &no_neighbor_passive_cmd);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 7923f076c1..d0a732b153 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -357,7 +357,7 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)
bgp_connected_delete(bgp, ifc);
}
- connected_free(ifc);
+ connected_free(&ifc);
return 0;
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index a2d4c0101e..7621d7ef0f 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2586,7 +2586,7 @@ int peer_group_delete(struct peer_group *group)
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
prefix)) {
- prefix_free(prefix);
+ prefix_free(&prefix);
}
list_delete(&group->listen_range[afi]);
}
@@ -7166,6 +7166,11 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
/* strict-capability-match */
if (peergroup_flag_check(peer, PEER_FLAG_STRICT_CAP_MATCH))
vty_out(vty, " neighbor %s strict-capability-match\n", addr);
+
+ /* Sender side AS path loop detection. */
+ if (peer->as_path_loop_detection)
+ vty_out(vty, " neighbor %s sender-as-path-loop-detection\n",
+ addr);
}
/* BGP peer configuration display function. */
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 9f6148488c..317f200b85 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1225,6 +1225,9 @@ struct peer {
char *hostname;
char *domainname;
+ /* Sender side AS path loop detection. */
+ bool as_path_loop_detection;
+
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(peer)
@@ -1447,9 +1450,6 @@ struct bgp_nlri {
#define BGP_VTY_PORT 2605
#define BGP_DEFAULT_CONFIG "bgpd.conf"
-/* Check AS path loop when we send NLRI. */
-/* #define BGP_SEND_ASPATH_CHECK */
-
/* BGP Dynamic Neighbors feature */
#define BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT 100
#define BGP_DYNAMIC_NEIGHBORS_LIMIT_MIN 1
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index fe8e874440..660442b492 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -1512,7 +1512,7 @@ static int rfapiNhlAddNodeRoutes(
}
seen_nexthops =
- skiplist_new(0, vnc_prefix_cmp, (void (*)(void *))prefix_free);
+ skiplist_new(0, vnc_prefix_cmp, prefix_free_lists);
for (bpi = rn->info; bpi; bpi = bpi->next) {
@@ -4359,7 +4359,7 @@ rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list,
it->rt_import_list = ecommunity_dup(rt_import_list);
it->rfg = rfg;
it->monitor_exterior_orphans =
- skiplist_new(0, NULL, (void (*)(void *))prefix_free);
+ skiplist_new(0, NULL, prefix_free_lists);
/*
* fill import route tables from RIBs
diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c
index df06105535..6e8969ad18 100644
--- a/bgpd/rfapi/vnc_import_bgp.c
+++ b/bgpd/rfapi/vnc_import_bgp.c
@@ -1807,8 +1807,7 @@ static void vnc_import_bgp_exterior_add_route_it(
RFAPI_MONITOR_EXTERIOR(rn)->source =
skiplist_new(
0, NULL,
- (void (*)(void *))
- prefix_free);
+ prefix_free_lists);
agg_lock_node(rn); /* for skiplist */
}
agg_lock_node(rn); /* for skiplist entry */
@@ -2194,8 +2193,7 @@ void vnc_import_bgp_exterior_add_route_interior(
->source) {
RFAPI_MONITOR_EXTERIOR(rn_interior)
->source = skiplist_new(
- 0, NULL,
- (void (*)(void *))prefix_free);
+ 0, NULL, prefix_free_lists);
agg_lock_node(rn_interior);
}
skiplist_insert(
@@ -2337,8 +2335,7 @@ void vnc_import_bgp_exterior_add_route_interior(
if (!RFAPI_MONITOR_EXTERIOR(rn_interior)->source) {
RFAPI_MONITOR_EXTERIOR(rn_interior)->source =
skiplist_new(
- 0, NULL,
- (void (*)(void *))prefix_free);
+ 0, NULL, prefix_free_lists);
agg_lock_node(rn_interior); /* sl */
}
skiplist_insert(
@@ -2527,8 +2524,7 @@ void vnc_import_bgp_exterior_del_route_interior(
if (!RFAPI_MONITOR_EXTERIOR(par)->source) {
RFAPI_MONITOR_EXTERIOR(par)->source =
skiplist_new(
- 0, NULL,
- (void (*)(void *))prefix_free);
+ 0, NULL, prefix_free_lists);
agg_lock_node(par); /* sl */
}
skiplist_insert(RFAPI_MONITOR_EXTERIOR(par)->source,
diff --git a/debian/copyright b/debian/copyright
index d1f28a65a2..edd73020bd 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -12,6 +12,7 @@ Copyright: 1996-2003 by the original Zebra authors:
2016-2018 by the FRRouting Project
Adam Fitzgerald 2017
Alex Couloumbis 2017
+ Alexandre Cassen 2001-2017
Alexandre Chappuis 2011
Alexis Fasquel 2015
Ali Rezaee 2018
@@ -47,6 +48,7 @@ Copyright: 1996-2003 by the original Zebra authors:
Christoffer Hansen 2018
Christoph Dwertmann 2018
Colin Petrie 2016
+ Cumulus Networks 2013-2019
Daniel Kozlowski 2012
Daniel Ng 2008
Daniel Walton 2015-2018
@@ -153,6 +155,7 @@ Copyright: 1996-2003 by the original Zebra authors:
Olivier Cochard-Labbé 2014
Olivier Dugeon 2014-2018
Ondrej Zajicek 2009
+ Open Source Routing / NetDEF 2012-2017
Pascal Mathis 2018
Paul Jakma 2002-2016
Paul P Komkoff Jr 2008
@@ -266,7 +269,7 @@ Copyright:
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Copyright 2007, 2008 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
-Files: babeld/babel_errors.* babeld/babel_memory.*
+Files: babeld/babel_errors.*
License: GPL-2+
Copyright: Copyright (C) 2017-2018 Donald Sharp, Cumulus Networks, Inc.
diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst
index c2e3724df2..6eef7532b3 100644
--- a/doc/developer/workflow.rst
+++ b/doc/developer/workflow.rst
@@ -163,6 +163,34 @@ releases have support for this feature request. Moreover, introducing features
requests may result in breaking the stability of the branch. LTS branches are first
done to bring long term support for stability.
+Development Branches
+--------------------
+
+Occassionally the community will desire the ability to work together
+on a feature that is considered useful to FRR. In this case the
+parties may ask the Maintainers for the creation of a development
+branch in the main FRR repository. Requirements for this to happen
+are:
+
+- A one paragraph description of the feature being implemented to
+ allow for the facilitation of discussion about the feature. This
+ might include pointers to relevant RFC's or presentations that
+ explain what is planned. This is intended to set a somewhat
+ low bar for organization.
+- A branch maintainer must be named. This person is responsible for
+ keeping the branch up to date, and general communication about the
+ project with the other FRR Maintainers. Additionally this person
+ must already be a FRR Maintainer.
+- Commits to this branch must follow the normal PR and commit process
+ as outlined in other areas of this document. The goal of this is
+ to prevent the current state where large features are submitted
+ and are so large they are difficult to review.
+
+After a development branch has completed the work together, a final
+review can be made and the branch merged into master. If a development
+branch is becomes un-maintained or not being actively worked on after
+three months then the Maintainers can decide to remove the branch.
+
Changelog
---------
The changelog will be the base for the release notes. A changelog entry for
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index b3e89a5f00..6c20658214 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1142,6 +1142,14 @@ Peer Filtering
on reflected routes. This option allows the modifications to be reflected as
well. Once enabled, it affects all reflected routes.
+.. index:: [no] neighbor PEER sender-as-path-loop-detection
+.. clicmd:: [no] neighbor PEER sender-as-path-loop-detection
+
+ Enable the detection of sender side AS path loops and filter the
+ bad routes before they are sent.
+
+ This setting is disabled by default.
+
.. _bgp-peer-group:
Peer Groups
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
index 3e09ec41bb..324f309290 100644
--- a/eigrpd/eigrp_network.c
+++ b/eigrpd/eigrp_network.c
@@ -327,8 +327,7 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p)
if (!IPV4_ADDR_SAME(&pref->u.prefix4, &p->u.prefix4))
return 0;
- prefix_ipv4_free(rn->info);
- rn->info = NULL;
+ prefix_ipv4_free((struct prefix_ipv4 **)&rn->info);
route_unlock_node(rn); /* initial reference */
/* Find interfaces that not configured already. */
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index 9cc612eaf1..56dbe3d85e 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -197,7 +197,7 @@ void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table,
list_delete(&pe->entries);
list_delete(&pe->rij);
eigrp_zebra_route_delete(eigrp, pe->destination);
- prefix_free(pe->destination);
+ prefix_free(&pe->destination);
rn->info = NULL;
route_unlock_node(rn); // Lookup above
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 9a0fdda0f9..3205f13922 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -189,7 +189,7 @@ static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS)
if (prefix_cmp(&ei->address, c->address) == 0)
eigrp_if_free(ei, INTERFACE_DOWN_BY_ZEBRA);
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 1d0e6549df..8343f7d85f 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -338,7 +338,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
if (ip) {
listnode_delete(circuit->ip_addrs, ip);
- prefix_ipv4_free(ip);
+ prefix_ipv4_free(&ip);
if (circuit->area)
lsp_regenerate_schedule(circuit->area,
circuit->is_type, 0);
@@ -358,7 +358,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
zlog_warn("End of addresses");
}
- prefix_ipv4_free(ipv4);
+ prefix_ipv4_free(&ipv4);
}
if (connected->address->family == AF_INET6) {
ipv6 = prefix_ipv6_new();
@@ -374,7 +374,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
}
if (ip6) {
listnode_delete(circuit->ipv6_link, ip6);
- prefix_ipv6_free(ip6);
+ prefix_ipv6_free(&ip6);
found = 1;
}
} else {
@@ -386,7 +386,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
}
if (ip6) {
listnode_delete(circuit->ipv6_non_link, ip6);
- prefix_ipv6_free(ip6);
+ prefix_ipv6_free(&ip6);
found = 1;
}
}
@@ -417,7 +417,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
lsp_regenerate_schedule(circuit->area, circuit->is_type,
0);
- prefix_ipv6_free(ipv6);
+ prefix_ipv6_free(&ipv6);
}
return;
}
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index bdf6869f5c..b4c699ccbb 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -128,7 +128,7 @@ static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
if (if_is_operative(ifp))
isis_circuit_del_addr(circuit_scan_by_ifp(ifp), c);
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 4df1fc0304..946b51e4ee 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -368,7 +368,7 @@ ldp_interface_address_delete(ZAPI_CALLBACK_ARGS)
ifp = ifc->ifp;
ifc2kaddr(ifp, ifc, &ka);
- connected_free(ifc);
+ connected_free(&ifc);
/* Filter invalid addresses. */
if (bad_addr(ka.af, &ka.addr))
diff --git a/lib/if.c b/lib/if.c
index 7c3606bbbf..9d0f13ecbd 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -140,6 +140,13 @@ static int if_cmp_index_func(const struct interface *ifp1,
return ifp1->ifindex - ifp2->ifindex;
}
+static void ifp_connected_free(void *arg)
+{
+ struct connected *c = arg;
+
+ connected_free(&c);
+}
+
/* Create new interface structure. */
static struct interface *if_new(vrf_id_t vrf_id)
{
@@ -153,7 +160,7 @@ static struct interface *if_new(vrf_id_t vrf_id)
ifp->vrf_id = vrf_id;
ifp->connected = list_new();
- ifp->connected->del = (void (*)(void *))connected_free;
+ ifp->connected->del = ifp_connected_free;
ifp->nbr_connected = list_new();
ifp->nbr_connected->del = (void (*)(void *))nbr_connected_free;
@@ -178,7 +185,7 @@ void if_destroy_via_zapi(struct interface *ifp)
if_set_index(ifp, IFINDEX_INTERNAL);
if (!ifp->configured)
- if_delete(ifp);
+ if_delete(&ifp);
}
void if_up_via_zapi(struct interface *ifp)
@@ -276,27 +283,29 @@ void if_delete_retain(struct interface *ifp)
}
/* Delete and free interface structure. */
-void if_delete(struct interface *ifp)
+void if_delete(struct interface **ifp)
{
+ struct interface *ptr = *ifp;
struct vrf *vrf;
- vrf = vrf_lookup_by_id(ifp->vrf_id);
+ vrf = vrf_lookup_by_id(ptr->vrf_id);
assert(vrf);
- IFNAME_RB_REMOVE(vrf, ifp);
- if (ifp->ifindex != IFINDEX_INTERNAL)
- IFINDEX_RB_REMOVE(vrf, ifp);
+ IFNAME_RB_REMOVE(vrf, ptr);
+ if (ptr->ifindex != IFINDEX_INTERNAL)
+ IFINDEX_RB_REMOVE(vrf, ptr);
- if_delete_retain(ifp);
+ if_delete_retain(ptr);
- list_delete(&ifp->connected);
- list_delete(&ifp->nbr_connected);
+ list_delete(&ptr->connected);
+ list_delete(&ptr->nbr_connected);
- if_link_params_free(ifp);
+ if_link_params_free(ptr);
- XFREE(MTYPE_TMP, ifp->desc);
+ XFREE(MTYPE_TMP, ptr->desc);
- XFREE(MTYPE_IF, ifp);
+ XFREE(MTYPE_IF, ptr);
+ *ifp = NULL;
}
/* Used only internally to check within VRF only */
@@ -866,24 +875,27 @@ struct nbr_connected *nbr_connected_new(void)
}
/* Free connected structure. */
-void connected_free(struct connected *connected)
+void connected_free(struct connected **connected)
{
- if (connected->address)
- prefix_free(connected->address);
+ struct connected *ptr = *connected;
+
+ if (ptr->address)
+ prefix_free(&ptr->address);
- if (connected->destination)
- prefix_free(connected->destination);
+ if (ptr->destination)
+ prefix_free(&ptr->destination);
- XFREE(MTYPE_CONNECTED_LABEL, connected->label);
+ XFREE(MTYPE_CONNECTED_LABEL, ptr->label);
- XFREE(MTYPE_CONNECTED, connected);
+ XFREE(MTYPE_CONNECTED, ptr);
+ *connected = NULL;
}
/* Free nbr connected structure. */
void nbr_connected_free(struct nbr_connected *connected)
{
if (connected->address)
- prefix_free(connected->address);
+ prefix_free(&connected->address);
XFREE(MTYPE_NBR_CONNECTED, connected);
}
@@ -1159,7 +1171,7 @@ void if_terminate(struct vrf *vrf)
ifp->node->info = NULL;
route_unlock_node(ifp->node);
}
- if_delete(ifp);
+ if_delete(&ifp);
}
}
@@ -1541,7 +1553,7 @@ static int lib_interface_destroy(enum nb_event event,
ifp = nb_running_unset_entry(dnode);
ifp->configured = false;
- if_delete(ifp);
+ if_delete(&ifp);
break;
}
diff --git a/lib/if.h b/lib/if.h
index 6322290937..4ca2e79572 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -513,7 +513,7 @@ extern void if_delete_retain(struct interface *);
/* Delete and free the interface structure: calls if_delete_retain and then
deletes it from the interface list and frees the structure. */
-extern void if_delete(struct interface *);
+extern void if_delete(struct interface **ifp);
extern int if_is_up(const struct interface *ifp);
extern int if_is_running(const struct interface *ifp);
@@ -543,7 +543,7 @@ extern ifindex_t ifname2ifindex(const char *ifname, vrf_id_t vrf_id);
/* Connected address functions. */
extern struct connected *connected_new(void);
-extern void connected_free(struct connected *);
+extern void connected_free(struct connected **connected);
extern void connected_add(struct interface *, struct connected *);
extern struct connected *
connected_add_by_prefix(struct interface *, struct prefix *, struct prefix *);
diff --git a/lib/prefix.c b/lib/prefix.c
index 5071ca8201..e2bf3b949c 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -905,9 +905,9 @@ struct prefix_ipv4 *prefix_ipv4_new(void)
}
/* Free prefix_ipv4 structure. */
-void prefix_ipv4_free(struct prefix_ipv4 *p)
+void prefix_ipv4_free(struct prefix_ipv4 **p)
{
- prefix_free((struct prefix *)p);
+ prefix_free((struct prefix **)p);
}
/* If given string is valid return 1 else return 0 */
@@ -1077,9 +1077,9 @@ struct prefix_ipv6 *prefix_ipv6_new(void)
}
/* Free prefix for IPv6. */
-void prefix_ipv6_free(struct prefix_ipv6 *p)
+void prefix_ipv6_free(struct prefix_ipv6 **p)
{
- prefix_free((struct prefix *)p);
+ prefix_free((struct prefix **)p);
}
/* If given string is valid return 1 else return 0 */
@@ -1484,10 +1484,18 @@ struct prefix *prefix_new(void)
return p;
}
+void prefix_free_lists(void *arg)
+{
+ struct prefix *p = arg;
+
+ prefix_free(&p);
+}
+
/* Free prefix structure. */
-void prefix_free(struct prefix *p)
+void prefix_free(struct prefix **p)
{
- XFREE(MTYPE_PREFIX, p);
+ XFREE(MTYPE_PREFIX, *p);
+ *p = NULL;
}
/* Utility function to convert ipv4 prefixes to Classful prefixes */
diff --git a/lib/prefix.h b/lib/prefix.h
index 784927616a..7a93c766a3 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -396,7 +396,11 @@ extern unsigned int prefix6_bit(const struct in6_addr *prefix,
const uint16_t prefixlen);
extern struct prefix *prefix_new(void);
-extern void prefix_free(struct prefix *);
+extern void prefix_free(struct prefix **p);
+/*
+ * Function to handle prefix_free being used as a del function.
+ */
+extern void prefix_free_lists(void *arg);
extern const char *prefix_family_str(const struct prefix *);
extern int prefix_blen(const struct prefix *);
extern int str2prefix(const char *, struct prefix *);
@@ -435,7 +439,7 @@ extern void prefix2sockunion(const struct prefix *, union sockunion *);
extern int str2prefix_eth(const char *, struct prefix_eth *);
extern struct prefix_ipv4 *prefix_ipv4_new(void);
-extern void prefix_ipv4_free(struct prefix_ipv4 *);
+extern void prefix_ipv4_free(struct prefix_ipv4 **p);
extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *);
extern void apply_mask_ipv4(struct prefix_ipv4 *);
@@ -460,7 +464,7 @@ extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen);
extern int netmask_str2prefix_str(const char *, const char *, char *);
extern struct prefix_ipv6 *prefix_ipv6_new(void);
-extern void prefix_ipv6_free(struct prefix_ipv6 *);
+extern void prefix_ipv6_free(struct prefix_ipv6 **p);
extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *);
extern void apply_mask_ipv6(struct prefix_ipv6 *);
diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c
index e4f614c7c4..9f828a1c7d 100644
--- a/nhrpd/nhrp_interface.c
+++ b/nhrpd/nhrp_interface.c
@@ -364,7 +364,7 @@ int nhrp_interface_address_delete(ZAPI_CALLBACK_ARGS)
nhrp_interface_update_address(
ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
- connected_free(ifc);
+ connected_free(&ifc);
return 0;
}
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index d8a6a39e1e..6832737ada 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -143,7 +143,7 @@ static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS)
ospf6_interface_state_update(c->ifp);
}
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index 73802ce13e..b9e78f4cd3 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -202,8 +202,9 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
struct interface *ifp;
struct ospf_interface *oi;
struct ospf_if_params *params;
- struct ospf_neighbor *nbr;
+ struct ospf_neighbor *nbr = NULL;
struct route_node *node;
+ struct route_node *n_node;
struct prefix p;
int status;
int old_status;
@@ -231,7 +232,28 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
if ((oi = node->info) == NULL)
continue;
- nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &p.u.prefix4);
+ /* walk the neighbor list for point-to-point network */
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
+ for (n_node = route_top(oi->nbrs); n_node;
+ n_node = route_next(n_node)) {
+ nbr = n_node->info;
+ if (nbr) {
+ /* skip myself */
+ if (nbr == oi->nbr_self) {
+ nbr = NULL;
+ continue;
+ }
+
+ /* Found the matching neighbor */
+ if (nbr->src.s_addr ==
+ p.u.prefix4.s_addr)
+ break;
+ }
+ }
+ } else {
+ nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &p.u.prefix4);
+ }
+
if (!nbr || !nbr->bfd_info)
continue;
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 1f5e0da944..5459e3b87c 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -902,11 +902,10 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
static void ospf_vl_if_delete(struct ospf_vl_data *vl_data)
{
- struct interface *ifp = vl_data->vl_oi->ifp;
vl_data->vl_oi->address->u.prefix4.s_addr = 0;
vl_data->vl_oi->address->prefixlen = 0;
ospf_if_free(vl_data->vl_oi);
- if_delete(ifp);
+ if_delete(&vl_data->vl_oi->ifp);
vlink_count--;
}
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 5678d545ba..68d9d3bf83 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -150,7 +150,7 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
rn = route_node_lookup(IF_OIFS(ifp), &p);
if (!rn) {
- connected_free(c);
+ connected_free(&c);
return 0;
}
@@ -163,7 +163,7 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
ospf_if_interface(c->ifp);
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index 069b3e6c9b..e0fd147b0e 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -133,10 +133,8 @@ DEFPY(pbr_map_match_src, pbr_map_match_src_cmd,
if (!pbrms->src)
pbrms->src = prefix_new();
prefix_copy(pbrms->src, prefix);
- } else {
- prefix_free(pbrms->src);
- pbrms->src = 0;
- }
+ } else
+ prefix_free(&pbrms->src);
pbr_map_check(pbrms);
@@ -162,10 +160,8 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
if (!pbrms->dst)
pbrms->dst = prefix_new();
prefix_copy(pbrms->dst, prefix);
- } else {
- prefix_free(pbrms->dst);
- pbrms->dst = NULL;
- }
+ } else
+ prefix_free(&pbrms->dst);
pbr_map_check(pbrms);
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 39e92467ab..719374e3b9 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -109,7 +109,7 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
"%s: %s deleted %s", __PRETTY_FUNCTION__, c->ifp->name,
prefix2str(c->address, buf, sizeof(buf)));
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 66e64cefa0..4ca38f10d1 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -191,11 +191,13 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
pim_upstream_del(pim_ifp->pim, ch->upstream,
__PRETTY_FUNCTION__);
- else
- zlog_warn("%s: Avoiding deletion of upstream with ref_count %d "
- "from ifchannel(%s): %s", __PRETTY_FUNCTION__,
- ch->upstream->ref_count, ch->interface->name,
- ch->sg_str);
+ else {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: Avoiding deletion of upstream with ref_count %d "
+ "from ifchannel(%s): %s", __PRETTY_FUNCTION__,
+ ch->upstream->ref_count, ch->interface->name,
+ ch->sg_str);
+ }
ch->upstream = NULL;
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 722ecb2a72..3f2aaf2bbe 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -767,7 +767,7 @@ static void delete_from_neigh_addr(struct interface *ifp,
other_neigh_str, ifp->name);
listnode_delete(neigh->prefix_list, p);
- prefix_free(p);
+ prefix_free(&p);
}
}
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index d93a360448..4fe3237395 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -757,8 +757,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
*/
if (!*hello_option_addr_list) {
*hello_option_addr_list = list_new();
- (*hello_option_addr_list)->del =
- (void (*)(void *))prefix_free;
+ (*hello_option_addr_list)->del = prefix_free_lists;
}
/*
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index dadcbbe65d..dfddee99d0 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -233,7 +233,7 @@ static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
pim_i_am_rp_re_evaluate(pim);
}
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 3173277ba7..4d48740606 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -648,7 +648,7 @@ int rip_interface_address_delete(ZAPI_CALLBACK_ARGS)
rip_apply_address_del(ifc);
}
- connected_free(ifc);
+ connected_free(&ifc);
}
return 0;
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 9209a76460..97113a180f 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -430,7 +430,7 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS)
/* Check wether this prefix needs to be removed. */
ripng_apply_address_del(ifc);
}
- connected_free(ifc);
+ connected_free(&ifc);
}
return 0;
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index da2aa2f539..cd577e9051 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -73,7 +73,7 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
if (!c)
return 0;
- connected_free(c);
+ connected_free(&c);
return 0;
}
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 976f892efb..a474613b4d 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -79,7 +79,7 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
if (!c)
return 0;
- connected_free(c);
+ connected_free(&c);
return 0;
}
@@ -260,7 +260,7 @@ static void static_nht_hash_free(void *data)
{
struct static_nht_data *nhtd = data;
- prefix_free(nhtd->nh);
+ prefix_free(&nhtd->nh);
XFREE(MTYPE_TMP, nhtd);
}
diff --git a/tools/tarsource.sh b/tools/tarsource.sh
index eee2a9739b..4843fe88b0 100755
--- a/tools/tarsource.sh
+++ b/tools/tarsource.sh
@@ -301,6 +301,11 @@ if $debian; then
--format='3.0 (custom)' --target-format='3.0 (quilt)' \
-b . frr_${PACKAGE_VERSION}.orig.tar.$zip frr_${DEBVER}.debian.tar.$zip
+ dpkg-genchanges -sa -S > ../frr_${DEBVER}_source.changes
+
+ test -n "$keyid" && debsign ../frr_${DEBVER}_source.changes -k"$keyid"
+
+ mv ../frr_${DEBVER}_source.changes "$outdir" || true
mv ../frr_${DEBVER}.dsc "$outdir" || true
mv ../frr_${DEBVER}.debian.tar.$zip "$outdir" || true
if test -h ../frr_${PACKAGE_VERSION}.orig.tar.$zip; then
@@ -309,12 +314,12 @@ if $debian; then
ln -s frr-${PACKAGE_VERSION}.tar.$zip "$outdir/frr_${PACKAGE_VERSION}.orig.tar.$zip" || true
cd "$outdir"
- test -n "$keyid" && debsign -k "$keyid" "frr_${DEBVER}.dsc"
lsfiles="$lsfiles \
frr_${DEBVER}.dsc \
frr_${DEBVER}.debian.tar.$zip \
- frr_${PACKAGE_VERSION}.orig.tar.$zip"
+ frr_${PACKAGE_VERSION}.orig.tar.$zip \
+ frr_${DEBVER}_source.changes"
fi
cd "$outdir"
diff --git a/zebra/connected.c b/zebra/connected.c
index 75f4f53bc6..0ff474d787 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -65,7 +65,7 @@ static void connected_withdraw(struct connected *ifc)
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
listnode_delete(ifc->ifp->connected, ifc);
- connected_free(ifc);
+ connected_free(&ifc);
}
}
@@ -177,7 +177,7 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
*/
if (connected_same(current, ifc)) {
/* nothing to do */
- connected_free(ifc);
+ connected_free(&ifc);
return;
}
diff --git a/zebra/interface.c b/zebra/interface.c
index daa93e36d1..eea80652e5 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -738,7 +738,7 @@ static void if_delete_connected(struct interface *ifp)
ZEBRA_IFC_CONFIGURED)) {
listnode_delete(ifp->connected,
ifc);
- connected_free(ifc);
+ connected_free(&ifc);
} else
last = node;
}
@@ -759,7 +759,7 @@ static void if_delete_connected(struct interface *ifp)
last = node;
else {
listnode_delete(ifp->connected, ifc);
- connected_free(ifc);
+ connected_free(&ifc);
}
} else {
last = node;
@@ -829,7 +829,7 @@ void if_delete_update(struct interface *ifp)
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("interface %s is being deleted from the system",
ifp->name);
- if_delete(ifp);
+ if_delete(&ifp);
}
}
@@ -2878,7 +2878,7 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
listnode_delete(ifp->connected, ifc);
- connected_free(ifc);
+ connected_free(&ifc);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -3103,7 +3103,7 @@ static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
listnode_delete(ifp->connected, ifc);
- connected_free(ifc);
+ connected_free(&ifc);
return CMD_WARNING_CONFIG_FAILED;
}