From 20eb8864bbaf19771502b6c1ed3f1e43186f97eb Mon Sep 17 00:00:00 2001 From: vivek Date: Thu, 29 Oct 2015 09:41:23 -0700 Subject: [PATCH] BGP: Check for duplicate and overlapping listen ranges When configuring listen ranges for allowing dynamic BGP neighbors, ensure that there are no duplicate or overlapping ones. This is necessary because at the time of handling an incoming connection, the first range that matches the source of the connection (and hence, its peer-group parameters) will be used. Signed-off-by: Vivek Venkataraman Reviewed-by: Donald Sharp Reviewed-by: Atul Patel Ticket: CM-5153 Reviewed By: CCR-3714 Testing Done: Manual verification --- bgpd/bgp_vty.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 38f3eb971e..bbacc22492 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -57,6 +57,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA extern struct in_addr router_id_zebra; +static struct peer_group * +listen_range_exists (struct bgp *bgp, struct prefix *range, int exact); + /* Utility function to get address family from current node. */ afi_t bgp_node_afi (struct vty *vty) @@ -2347,6 +2350,38 @@ DEFUN (no_bgp_listen_limit, } +/* + * Check if this listen range is already configured. Check for exact + * match or overlap based on input. + */ +static struct peer_group * +listen_range_exists (struct bgp *bgp, struct prefix *range, int exact) +{ + struct listnode *node, *nnode; + struct listnode *node1, *nnode1; + struct peer_group *group; + struct prefix *lr; + afi_t afi; + int match; + + afi = family2afi(range->family); + for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group)) + { + for (ALL_LIST_ELEMENTS (group->listen_range[afi], node1, + nnode1, lr)) + { + if (exact) + match = prefix_same (range, lr); + else + match = (prefix_match (range, lr) || prefix_match (lr, range)); + if (match) + return group; + } + } + + return NULL; +} + DEFUN (bgp_listen_range, bgp_listen_range_cmd, LISTEN_RANGE_CMD "peer-group WORD" , @@ -2357,7 +2392,7 @@ DEFUN (bgp_listen_range, { struct bgp *bgp; struct prefix range; - struct peer_group *group; + struct peer_group *group, *existing_group; afi_t afi; int ret; @@ -2386,6 +2421,27 @@ DEFUN (bgp_listen_range, apply_mask (&range); + /* Check if same listen range is already configured. */ + existing_group = listen_range_exists (bgp, &range, 1); + if (existing_group) + { + if (strcmp (existing_group->name, argv[1]) == 0) + return CMD_SUCCESS; + else + { + vty_out (vty, "%% Same listen range is attached to peer-group %s%s", + existing_group->name, VTY_NEWLINE); + return CMD_WARNING; + } + } + + /* Check if an overlapping listen range exists. */ + if (listen_range_exists (bgp, &range, 0)) + { + vty_out (vty, "%% Listen range overlaps with existing listen range%s", + VTY_NEWLINE); + return CMD_WARNING; + } group = peer_group_lookup (bgp, argv[1]); if (! group) -- 2.39.5