summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_route.c211
-rw-r--r--bgpd/bgp_route.h4
-rw-r--r--bgpd/bgp_zebra.c10
-rw-r--r--bgpd/bgpd.c5
-rw-r--r--bgpd/bgpd.h6
5 files changed, 173 insertions, 63 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index afb37aeef6..44377c3692 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -13995,7 +13995,7 @@ ALIAS (show_bgp_instance_neighbor_damp,
#endif /* HAVE_IPV6 */
-struct bgp_table *bgp_distance_table;
+struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
struct bgp_distance
{
@@ -14023,12 +14023,17 @@ bgp_distance_set (struct vty *vty, const char *distance_str,
const char *ip_str, const char *access_list_str)
{
int ret;
- struct prefix_ipv4 p;
+ afi_t afi;
+ safi_t safi;
+ struct prefix p;
u_char distance;
struct bgp_node *rn;
struct bgp_distance *bdistance;
- ret = str2prefix_ipv4 (ip_str, &p);
+ afi = bgp_node_afi (vty);
+ safi = bgp_node_safi (vty);
+
+ ret = str2prefix (ip_str, &p);
if (ret == 0)
{
vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
@@ -14038,7 +14043,7 @@ bgp_distance_set (struct vty *vty, const char *distance_str,
distance = atoi (distance_str);
/* Get BGP distance node. */
- rn = bgp_node_get (bgp_distance_table, (struct prefix *) &p);
+ rn = bgp_node_get (bgp_distance_table[afi][safi], (struct prefix *) &p);
if (rn->info)
{
bdistance = rn->info;
@@ -14070,19 +14075,24 @@ bgp_distance_unset (struct vty *vty, const char *distance_str,
const char *ip_str, const char *access_list_str)
{
int ret;
+ afi_t afi;
+ safi_t safi;
+ struct prefix p;
int distance;
- struct prefix_ipv4 p;
struct bgp_node *rn;
struct bgp_distance *bdistance;
- ret = str2prefix_ipv4 (ip_str, &p);
+ afi = bgp_node_afi (vty);
+ safi = bgp_node_safi (vty);
+
+ ret = str2prefix (ip_str, &p);
if (ret == 0)
{
vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
return CMD_WARNING;
}
- rn = bgp_node_lookup (bgp_distance_table, (struct prefix *)&p);
+ rn = bgp_node_lookup (bgp_distance_table[afi][safi], (struct prefix *)&p);
if (! rn)
{
vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
@@ -14111,10 +14121,11 @@ bgp_distance_unset (struct vty *vty, const char *distance_str,
/* Apply BGP information to distance method. */
u_char
-bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
+bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi,
+ safi_t safi, struct bgp *bgp)
{
struct bgp_node *rn;
- struct prefix_ipv4 q;
+ struct prefix q;
struct peer *peer;
struct bgp_distance *bdistance;
struct access_list *alist;
@@ -14123,21 +14134,11 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
if (! bgp)
return 0;
- if (p->family != AF_INET)
- return 0;
-
peer = rinfo->peer;
- if (peer->su.sa.sa_family != AF_INET)
- return 0;
-
- memset (&q, 0, sizeof (struct prefix_ipv4));
- q.family = AF_INET;
- q.prefix = peer->su.sin.sin_addr;
- q.prefixlen = IPV4_MAX_BITLEN;
-
/* Check source address. */
- rn = bgp_node_match (bgp_distance_table, (struct prefix *) &q);
+ sockunion2hostprefix (&peer->su, &q);
+ rn = bgp_node_match (bgp_distance_table[afi][safi], &q);
if (rn)
{
bdistance = rn->info;
@@ -14145,7 +14146,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
if (bdistance->access_list)
{
- alist = access_list_lookup (AFI_IP, bdistance->access_list);
+ alist = access_list_lookup (afi, bdistance->access_list);
if (alist && access_list_apply (alist, p) == FILTER_PERMIT)
return bdistance->distance;
}
@@ -14154,7 +14155,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
}
/* Backdoor check. */
- rn = bgp_node_lookup (bgp->route[AFI_IP][SAFI_UNICAST], p);
+ rn = bgp_node_lookup (bgp->route[afi][safi], p);
if (rn)
{
bgp_static = rn->info;
@@ -14162,8 +14163,8 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
if (bgp_static->backdoor)
{
- if (bgp->distance_local)
- return bgp->distance_local;
+ if (bgp->distance_local[afi][safi])
+ return bgp->distance_local[afi][safi];
else
return ZEBRA_IBGP_DISTANCE_DEFAULT;
}
@@ -14171,14 +14172,14 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
if (peer->sort == BGP_PEER_EBGP)
{
- if (bgp->distance_ebgp)
- return bgp->distance_ebgp;
+ if (bgp->distance_ebgp[afi][safi])
+ return bgp->distance_ebgp[afi][safi];
return ZEBRA_EBGP_DISTANCE_DEFAULT;
}
else
{
- if (bgp->distance_ibgp)
- return bgp->distance_ibgp;
+ if (bgp->distance_ibgp[afi][safi])
+ return bgp->distance_ibgp[afi][safi];
return ZEBRA_IBGP_DISTANCE_DEFAULT;
}
}
@@ -14193,12 +14194,16 @@ DEFUN (bgp_distance,
"Distance for local routes\n")
{
struct bgp *bgp;
+ afi_t afi;
+ safi_t safi;
bgp = vty->index;
+ afi = bgp_node_afi (vty);
+ safi = bgp_node_safi (vty);
- bgp->distance_ebgp = atoi (argv[0]);
- bgp->distance_ibgp = atoi (argv[1]);
- bgp->distance_local = atoi (argv[2]);
+ bgp->distance_ebgp[afi][safi] = atoi (argv[0]);
+ bgp->distance_ibgp[afi][safi] = atoi (argv[1]);
+ bgp->distance_local[afi][safi] = atoi (argv[2]);
return CMD_SUCCESS;
}
@@ -14213,12 +14218,16 @@ DEFUN (no_bgp_distance,
"Distance for local routes\n")
{
struct bgp *bgp;
+ afi_t afi;
+ safi_t safi;
bgp = vty->index;
+ afi = bgp_node_afi (vty);
+ safi = bgp_node_safi (vty);
- bgp->distance_ebgp= 0;
- bgp->distance_ibgp = 0;
- bgp->distance_local = 0;
+ bgp->distance_ebgp[afi][safi] = 0;
+ bgp->distance_ibgp[afi][safi] = 0;
+ bgp->distance_local[afi][safi] = 0;
return CMD_SUCCESS;
}
@@ -14277,6 +14286,54 @@ DEFUN (no_bgp_distance_source_access_list,
return CMD_SUCCESS;
}
+DEFUN (ipv6_bgp_distance_source,
+ ipv6_bgp_distance_source_cmd,
+ "distance <1-255> X:X::X:X/M",
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n")
+{
+ bgp_distance_set (vty, argv[0], argv[1], NULL);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_bgp_distance_source,
+ no_ipv6_bgp_distance_source_cmd,
+ "no distance <1-255> X:X::X:X/M",
+ NO_STR
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n")
+{
+ bgp_distance_unset (vty, argv[0], argv[1], NULL);
+ return CMD_SUCCESS;
+}
+
+DEFUN (ipv6_bgp_distance_source_access_list,
+ ipv6_bgp_distance_source_access_list_cmd,
+ "distance <1-255> X:X::X:X/M WORD",
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n"
+ "Access list name\n")
+{
+ bgp_distance_set (vty, argv[0], argv[1], argv[2]);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_bgp_distance_source_access_list,
+ no_ipv6_bgp_distance_source_access_list_cmd,
+ "no distance <1-255> X:X::X:X/M WORD",
+ NO_STR
+ "Define an administrative distance\n"
+ "Administrative distance\n"
+ "IP source prefix\n"
+ "Access list name\n")
+{
+ bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
+ return CMD_SUCCESS;
+}
+
DEFUN (bgp_damp_set,
bgp_damp_set_cmd,
"bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
@@ -14711,40 +14768,53 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
}
int
-bgp_config_write_distance (struct vty *vty, struct bgp *bgp)
+bgp_config_write_distance (struct vty *vty, struct bgp *bgp, afi_t afi,
+ safi_t safi, int *write)
{
struct bgp_node *rn;
struct bgp_distance *bdistance;
/* Distance configuration. */
- if (bgp->distance_ebgp
- && bgp->distance_ibgp
- && bgp->distance_local
- && (bgp->distance_ebgp != ZEBRA_EBGP_DISTANCE_DEFAULT
- || bgp->distance_ibgp != ZEBRA_IBGP_DISTANCE_DEFAULT
- || bgp->distance_local != ZEBRA_IBGP_DISTANCE_DEFAULT))
- vty_out (vty, " distance bgp %d %d %d%s",
- bgp->distance_ebgp, bgp->distance_ibgp, bgp->distance_local,
- VTY_NEWLINE);
-
- for (rn = bgp_table_top (bgp_distance_table); rn; rn = bgp_route_next (rn))
+ if (bgp->distance_ebgp[afi][safi]
+ && bgp->distance_ibgp[afi][safi]
+ && bgp->distance_local[afi][safi]
+ && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
+ || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
+ || bgp->distance_local[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT))
+ {
+ bgp_config_write_family_header (vty, afi, safi, write);
+ vty_out (vty, " distance bgp %d %d %d%s",
+ bgp->distance_ebgp[afi][safi], bgp->distance_ibgp[afi][safi],
+ bgp->distance_local[afi][safi], VTY_NEWLINE);
+ }
+
+ for (rn = bgp_table_top (bgp_distance_table[afi][safi]); rn;
+ rn = bgp_route_next (rn))
if ((bdistance = rn->info) != NULL)
{
- vty_out (vty, " distance %d %s/%d %s%s", bdistance->distance,
- inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
+ char buf[PREFIX_STRLEN];
+
+ bgp_config_write_family_header (vty, afi, safi, write);
+ vty_out (vty, " distance %d %s %s%s", bdistance->distance,
+ prefix2str (&rn->p, buf, sizeof (buf)),
bdistance->access_list ? bdistance->access_list : "",
VTY_NEWLINE);
}
- return 0;
+ return *write;
}
/* Allocate routing table structure and install commands. */
void
bgp_route_init (void)
{
+ afi_t afi;
+ safi_t safi;
+
/* Init BGP distance table. */
- bgp_distance_table = bgp_table_init (AFI_IP, SAFI_UNICAST);
+ 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);
/* IPv4 BGP commands. */
install_element (BGP_NODE, &bgp_table_map_cmd);
@@ -15178,6 +15248,34 @@ bgp_route_init (void)
install_element (BGP_NODE, &no_bgp_distance_source_cmd);
install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_distance2_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
+ install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_distance_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_distance2_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
+ install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV6_NODE, &bgp_distance_cmd);
+ install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd);
+ install_element (BGP_IPV6_NODE, &no_bgp_distance2_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV6M_NODE, &bgp_distance_cmd);
+ install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd);
+ install_element (BGP_IPV6M_NODE, &no_bgp_distance2_cmd);
+ install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
+ install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
+ install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd);
+ install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
install_element (BGP_NODE, &bgp_damp_set_cmd);
install_element (BGP_NODE, &bgp_damp_set2_cmd);
@@ -15203,6 +15301,13 @@ bgp_route_init (void)
void
bgp_route_finish (void)
{
- bgp_table_unlock (bgp_distance_table);
- bgp_distance_table = NULL;
+ 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;
+ }
}
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 0dce5da572..bb06204689 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -307,14 +307,14 @@ extern void bgp_add_eoiu_mark (struct bgp *);
extern int bgp_config_write_table_map (struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_network (struct vty *, struct bgp *, afi_t, safi_t, int *);
-extern int bgp_config_write_distance (struct vty *, struct bgp *);
+extern int bgp_config_write_distance (struct vty *, struct bgp *, afi_t, safi_t, int *);
extern void bgp_aggregate_increment (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
extern void bgp_aggregate_decrement (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
-extern u_char bgp_distance_apply (struct prefix *, struct bgp_info *, struct bgp *);
+extern u_char bgp_distance_apply (struct prefix *, struct bgp_info *, afi_t, safi_t, struct bgp *);
extern afi_t bgp_node_afi (struct vty *);
extern safi_t bgp_node_safi (struct vty *);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 11e888d7e9..8ecd025397 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1367,8 +1367,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.tag = tag;
}
- distance = bgp_distance_apply (p, info, bgp);
-
+ distance = bgp_distance_apply (p, info, afi, safi, bgp);
if (distance)
{
SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
@@ -1554,6 +1553,13 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.tag = tag;
}
+ distance = bgp_distance_apply (p, info, afi, safi, bgp);
+ if (distance)
+ {
+ SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
+ api.distance = distance;
+ }
+
if (p->family == AF_INET)
{
if (bgp_debug_zebra(p))
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 71c2c84e61..403468a630 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -7123,6 +7123,8 @@ bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
struct peer_group *group;
struct listnode *node, *nnode;
+ bgp_config_write_distance (vty, bgp, afi, safi, &write);
+
bgp_config_write_network (vty, bgp, afi, safi, &write);
bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
@@ -7371,9 +7373,6 @@ bgp_config_write (struct vty *vty)
bgp_config_write_peer_global (vty, bgp, peer);
}
- /* Distance configuration. */
- bgp_config_write_distance (vty, bgp);
-
/* listen range and limit for dynamic BGP neighbors */
bgp_config_write_listen (vty, bgp);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index ee105201e8..f6e8598494 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -320,9 +320,9 @@ struct bgp
#define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5
/* BGP distance configuration. */
- u_char distance_ebgp;
- u_char distance_ibgp;
- u_char distance_local;
+ u_char distance_ebgp[AFI_MAX][SAFI_MAX];
+ u_char distance_ibgp[AFI_MAX][SAFI_MAX];
+ u_char distance_local[AFI_MAX][SAFI_MAX];
/* BGP default local-preference. */
u_int32_t default_local_pref;