mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 18:25:00 +00:00
Merge branch 'cmaster-next' into vtysh-grammar
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com> Conflicts: bgpd/bgp_encap.c bgpd/bgp_route.c lib/command.c lib/command.h ospf6d/ospf6d.c vtysh/vtysh.c
This commit is contained in:
commit
39e92c066f
@ -1144,8 +1144,7 @@ const u_int8_t attr_flags_values [] = {
|
||||
[BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
|
||||
[BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
|
||||
};
|
||||
static const size_t attr_flags_values_max =
|
||||
sizeof (attr_flags_values) / sizeof (attr_flags_values[0]);
|
||||
static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
|
||||
|
||||
static int
|
||||
bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
|
||||
|
@ -403,17 +403,22 @@ community_str_get (struct community *com, int i)
|
||||
static int
|
||||
community_regexp_include (regex_t * reg, struct community *com, int i)
|
||||
{
|
||||
const char *str;
|
||||
char *str;
|
||||
int rv;
|
||||
|
||||
/* When there is no communities attribute it is treated as empty
|
||||
* string. */
|
||||
if (com == NULL || com->size == 0)
|
||||
str = "";
|
||||
str = XSTRDUP(MTYPE_COMMUNITY_STR, "");
|
||||
else
|
||||
str = community_str_get (com, i);
|
||||
|
||||
/* Regular expression match. */
|
||||
if (regexec (reg, str, 0, NULL, 0) == 0)
|
||||
rv = regexec (reg, str, 0, NULL, 0);
|
||||
|
||||
XFREE(MTYPE_COMMUNITY_STR, str);
|
||||
|
||||
if (rv == 0)
|
||||
return 1;
|
||||
|
||||
/* No match. */
|
||||
|
@ -631,24 +631,23 @@ DEFUN (show_bgp_ipv4_encap_neighbor_routes,
|
||||
"Display routes learned from neighbor\n")
|
||||
{
|
||||
int idx_peer = 5;
|
||||
union sockunion *su;
|
||||
union sockunion su;
|
||||
struct peer *peer;
|
||||
|
||||
su = sockunion_str2su (argv[idx_peer]->arg);
|
||||
if (su == NULL)
|
||||
|
||||
if (sockunion_str2su (argv[idx_peer]->arg))
|
||||
{
|
||||
vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
peer = peer_lookup (NULL, su);
|
||||
peer = peer_lookup (NULL, &su);
|
||||
if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP])
|
||||
{
|
||||
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, su, 0);
|
||||
return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0);
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
DEFUN (show_bgp_ipv6_encap_neighbor_routes,
|
||||
@ -663,24 +662,23 @@ DEFUN (show_bgp_ipv6_encap_neighbor_routes,
|
||||
"Display routes learned from neighbor\n")
|
||||
{
|
||||
int idx_peer = 5;
|
||||
union sockunion *su;
|
||||
union sockunion su;
|
||||
struct peer *peer;
|
||||
|
||||
su = sockunion_str2su (argv[idx_peer]->arg);
|
||||
if (su == NULL)
|
||||
if (str2sockunion(argv[idx_peer]->arg, &su))
|
||||
{
|
||||
vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
peer = peer_lookup (NULL, su);
|
||||
peer = peer_lookup (NULL, &su);
|
||||
if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP])
|
||||
{
|
||||
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, su, 0);
|
||||
return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -701,7 +699,7 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes,
|
||||
int idx_rd = 5;
|
||||
int idx_peer = 7;
|
||||
int ret;
|
||||
union sockunion *su;
|
||||
union sockunion su;
|
||||
struct peer *peer;
|
||||
struct prefix_rd prd;
|
||||
|
||||
@ -712,21 +710,20 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes,
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
su = sockunion_str2su (argv[idx_peer]->arg);
|
||||
if (su == NULL)
|
||||
if (str2sockunion(argv[idx_peer]->arg, &su))
|
||||
{
|
||||
vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
peer = peer_lookup (NULL, su);
|
||||
peer = peer_lookup (NULL, &su);
|
||||
if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP])
|
||||
{
|
||||
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, su, 0);
|
||||
return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0);
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
|
||||
@ -746,7 +743,7 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
|
||||
int idx_rd = 5;
|
||||
int idx_peer = 7;
|
||||
int ret;
|
||||
union sockunion *su;
|
||||
union sockunion su;
|
||||
struct peer *peer;
|
||||
struct prefix_rd prd;
|
||||
|
||||
@ -757,21 +754,20 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
su = sockunion_str2su (argv[idx_peer]->arg);
|
||||
if (su == NULL)
|
||||
if (str2sockunion(argv[idx_peer]->arg, &su))
|
||||
{
|
||||
vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
peer = peer_lookup (NULL, su);
|
||||
peer = peer_lookup (NULL, &su);
|
||||
if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP])
|
||||
{
|
||||
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, su, 0);
|
||||
return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, &su, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -253,9 +253,6 @@ bgp_exit (int status)
|
||||
bgp_delete (bgp);
|
||||
list_free (bm->bgp);
|
||||
|
||||
/* reverse bgp_attr_init */
|
||||
bgp_attr_finish ();
|
||||
|
||||
/* reverse bgp_dump_init */
|
||||
bgp_dump_finish ();
|
||||
|
||||
@ -265,6 +262,9 @@ bgp_exit (int status)
|
||||
/* cleanup route maps */
|
||||
bgp_route_map_terminate();
|
||||
|
||||
/* reverse bgp_attr_init */
|
||||
bgp_attr_finish ();
|
||||
|
||||
/* reverse access_list_init */
|
||||
access_list_add_hook (NULL);
|
||||
access_list_delete_hook (NULL);
|
||||
|
221
bgpd/bgp_route.c
221
bgpd/bgp_route.c
@ -8110,15 +8110,6 @@ DEFUN (show_ip_bgp_ipv4,
|
||||
if (strmatch(argv[idx]->text, "cidr-only"))
|
||||
return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
|
||||
|
||||
else if (strmatch(argv[idx]->text, "dampening"))
|
||||
{
|
||||
if (strmatch(argv[idx + 1]->text, "dampened-paths"))
|
||||
return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
|
||||
|
||||
else if (strmatch(argv[idx + 1]->text, "flap-statistics"))
|
||||
return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
|
||||
}
|
||||
|
||||
else if (strmatch(argv[idx]->text, "dampened-paths"))
|
||||
return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
|
||||
|
||||
@ -8295,10 +8286,14 @@ DEFUN (show_ip_bgp_instance_all,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bgp_show_regexp (struct vty *vty, int argc, struct cmd_token **argv, afi_t afi,
|
||||
safi_t safi, enum bgp_show_type type)
|
||||
{
|
||||
return CMD_SUCCESS;
|
||||
/* XXX(vtysh-grammar): Needs updating for new CLI backend.
|
||||
|
||||
int i;
|
||||
struct buffer *b;
|
||||
char *regstr;
|
||||
@ -8338,6 +8333,7 @@ bgp_show_regexp (struct vty *vty, int argc, struct cmd_token **argv, afi_t afi,
|
||||
rc = bgp_show (vty, NULL, afi, safi, type, regex, 0);
|
||||
bgp_regex_free (regex);
|
||||
return rc;
|
||||
*/
|
||||
}
|
||||
|
||||
static int
|
||||
@ -9827,7 +9823,7 @@ DEFUN (show_ip_bgp_neighbor_routes,
|
||||
return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj);
|
||||
}
|
||||
|
||||
struct bgp_table *bgp_distance_table;
|
||||
struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
|
||||
|
||||
struct bgp_distance
|
||||
{
|
||||
@ -9855,12 +9851,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);
|
||||
@ -9870,7 +9871,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;
|
||||
@ -9902,19 +9903,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);
|
||||
@ -9943,10 +9949,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;
|
||||
@ -9955,21 +9962,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;
|
||||
@ -9977,7 +9974,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;
|
||||
}
|
||||
@ -9986,7 +9983,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;
|
||||
@ -9994,8 +9991,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;
|
||||
}
|
||||
@ -10003,14 +10000,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;
|
||||
}
|
||||
}
|
||||
@ -10028,12 +10025,16 @@ DEFUN (bgp_distance,
|
||||
int idx_number_2 = 3;
|
||||
int idx_number_3 = 4;
|
||||
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[idx_number]->arg);
|
||||
bgp->distance_ibgp = atoi (argv[idx_number_2]->arg);
|
||||
bgp->distance_local = atoi (argv[idx_number_3]->arg);
|
||||
bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg);
|
||||
bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg);
|
||||
bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -10048,12 +10049,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;
|
||||
}
|
||||
|
||||
@ -10116,6 +10121,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[1]->arg, argv[2]->arg, 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[2]->arg, argv[3]->arg, 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[1]->arg, argv[2]->arg, argv[3]->arg);
|
||||
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[2]->arg, argv[3]->arg, argv[4]->arg);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (bgp_damp_set,
|
||||
bgp_damp_set_cmd,
|
||||
"bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
|
||||
@ -10484,40 +10537,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);
|
||||
@ -10656,6 +10722,30 @@ 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, &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, &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, &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, &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_unset_cmd);
|
||||
@ -10670,6 +10760,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;
|
||||
}
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -2268,7 +2268,6 @@ route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
|
||||
struct in6_addr peer_address;
|
||||
struct bgp_info *bgp_info;
|
||||
struct peer *peer;
|
||||
char peer_addr_buf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (type == RMAP_BGP)
|
||||
{
|
||||
@ -2281,10 +2280,7 @@ route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
|
||||
&& peer->su_remote
|
||||
&& sockunion_family (peer->su_remote) == AF_INET6)
|
||||
{
|
||||
inet_pton (AF_INET6, sockunion2str (peer->su_remote,
|
||||
peer_addr_buf,
|
||||
INET6_ADDRSTRLEN),
|
||||
&peer_address);
|
||||
peer_address = peer->su_remote->sin6.sin6_addr;
|
||||
/* Set next hop value and length in attribute. */
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
|
||||
{
|
||||
|
@ -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))
|
||||
|
35
bgpd/bgpd.c
35
bgpd/bgpd.c
@ -6193,7 +6193,6 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
|
||||
}
|
||||
|
||||
/* Display peer uptime.*/
|
||||
/* XXX: why does this function return char * when it takes buffer? */
|
||||
char *
|
||||
peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json)
|
||||
{
|
||||
@ -6216,7 +6215,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
|
||||
if (uptime2 == 0)
|
||||
{
|
||||
if (use_json)
|
||||
json_object_string_add(json, "peerUptime", "never");
|
||||
{
|
||||
json_object_string_add(json, "peerUptime", "never");
|
||||
json_object_int_add(json, "peerUptimeMsec", 0);
|
||||
}
|
||||
else
|
||||
snprintf (buf, len, "never");
|
||||
return buf;
|
||||
@ -6232,24 +6234,6 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
|
||||
#define ONE_WEEK_SECOND ONE_DAY_SECOND*7
|
||||
#define ONE_YEAR_SECOND ONE_DAY_SECOND*365
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
unsigned long time_store;
|
||||
unsigned long sec_msec = 1000;
|
||||
unsigned long minute_msec = sec_msec * 60;
|
||||
unsigned long hour_msec = minute_msec * 60;
|
||||
unsigned long day_msec = hour_msec * 24;
|
||||
unsigned long year_msec = day_msec *365;
|
||||
|
||||
time_store =
|
||||
year_msec * tm->tm_year +
|
||||
day_msec * tm->tm_yday +
|
||||
hour_msec * tm->tm_hour +
|
||||
minute_msec * tm->tm_min +
|
||||
sec_msec * tm->tm_sec;
|
||||
json_object_int_add(json, "peerUptimeMsec", time_store);
|
||||
}
|
||||
|
||||
if (uptime1 < ONE_DAY_SECOND)
|
||||
snprintf (buf, len, "%02d:%02d:%02d",
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
@ -6264,6 +6248,12 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
|
||||
tm->tm_year - 70, tm->tm_yday/7,
|
||||
tm->tm_yday - ((tm->tm_yday/7) * 7));
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
json_object_string_add(json, "peerUptime", buf);
|
||||
json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -7123,6 +7113,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 +7363,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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -979,7 +979,7 @@ isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty,
|
||||
vty_out(vty, " %s%s", buf, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
if (circuit->ipv6_link && listcount(circuit->ipv6_non_link) > 0)
|
||||
if (circuit->ipv6_non_link && listcount(circuit->ipv6_non_link) > 0)
|
||||
{
|
||||
vty_out(vty, " IPv6 Prefixes:%s", VTY_NEWLINE);
|
||||
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ip_addr))
|
||||
|
@ -230,7 +230,7 @@ route_set_metric_compile(const char *arg)
|
||||
if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC)
|
||||
return NULL;
|
||||
|
||||
ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(ret));
|
||||
ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret));
|
||||
*ret = metric;
|
||||
|
||||
return ret;
|
||||
|
@ -213,6 +213,18 @@ argv_find (struct cmd_token **argv, int argc, const char *text, int *index)
|
||||
return found;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
cmd_hash_key (void *p)
|
||||
{
|
||||
return (uintptr_t) p;
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_hash_cmp (const void *a, const void *b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
/* Install top node of command vector. */
|
||||
void
|
||||
install_node (struct cmd_node *node,
|
||||
@ -225,6 +237,7 @@ install_node (struct cmd_node *node,
|
||||
// add start node
|
||||
struct cmd_token *token = new_cmd_token (START_TKN, NULL, NULL);
|
||||
graph_new_node (node->cmdgraph, token, (void (*)(void *)) &del_cmd_token);
|
||||
node->cmd_hash = hash_create (cmd_hash_key, cmd_hash_cmp);
|
||||
}
|
||||
|
||||
/* Breaking up string into each command piece. I assume given
|
||||
@ -332,8 +345,12 @@ install_element (enum node_type ntype, struct cmd_element *cmd)
|
||||
|
||||
/* cmd_init hasn't been called */
|
||||
if (!cmdvec)
|
||||
return;
|
||||
|
||||
{
|
||||
fprintf (stderr, "%s called before cmd_init, breakage likely\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
cnode = vector_slot (cmdvec, ntype);
|
||||
|
||||
if (cnode == NULL)
|
||||
@ -342,19 +359,17 @@ install_element (enum node_type ntype, struct cmd_element *cmd)
|
||||
ntype);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// add node to command graph and command vector
|
||||
// idiotic O(n) deduplication logic, should just use a merkle tree
|
||||
for (unsigned int i = 0; i < vector_active (cnode->cmd_vector); i++)
|
||||
{
|
||||
struct cmd_element *existing = vector_slot (cnode->cmd_vector, i);
|
||||
if (strmatch (existing->string, cmd->string))
|
||||
|
||||
if (hash_lookup (cnode->cmd_hash, cmd) != NULL)
|
||||
{
|
||||
zlog_warn ("Duplicate command: %s\n", cmd->string);
|
||||
fprintf (stderr,
|
||||
"Multiple command installs to node %d of command:\n%s\n",
|
||||
ntype, cmd->string);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
assert (hash_get (cnode->cmd_hash, cmd, hash_alloc_intern));
|
||||
|
||||
command_parse_format (cnode->cmdgraph, cmd);
|
||||
vector_set (cnode->cmd_vector, cmd);
|
||||
|
||||
@ -2433,6 +2448,9 @@ cmd_terminate ()
|
||||
// deleting the graph delets the cmd_element as well
|
||||
graph_delete_graph (cmd_node->cmdgraph);
|
||||
vector_free (cmd_node->cmd_vector);
|
||||
hash_clean (cmd_node->cmd_hash, NULL);
|
||||
hash_free (cmd_node->cmd_hash);
|
||||
cmd_node->cmd_hash = NULL;
|
||||
}
|
||||
|
||||
vector_free (cmdvec);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "lib/route_types.h"
|
||||
#include "graph.h"
|
||||
#include "memory.h"
|
||||
#include "hash.h"
|
||||
|
||||
DECLARE_MTYPE(HOST)
|
||||
|
||||
@ -152,6 +153,9 @@ struct cmd_node
|
||||
|
||||
/* Vector of this node's command list. */
|
||||
vector cmd_vector;
|
||||
|
||||
/* Hashed index of command node list, for de-dupping primarily */
|
||||
struct hash *cmd_hash;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -54,6 +54,12 @@ json_object_int_add(struct json_object* obj, const char *key, int32_t i)
|
||||
json_object_object_add(obj, key, json_object_new_int(i));
|
||||
}
|
||||
|
||||
void
|
||||
json_object_long_add(struct json_object* obj, const char *key, int64_t i)
|
||||
{
|
||||
json_object_object_add(obj, key, json_object_new_int64(i));
|
||||
}
|
||||
|
||||
void
|
||||
json_object_boolean_false_add(struct json_object* obj, const char *key)
|
||||
{
|
||||
|
@ -39,6 +39,8 @@ extern void json_object_string_add(struct json_object* obj, const char *key,
|
||||
const char *s);
|
||||
extern void json_object_int_add(struct json_object* obj, const char *key,
|
||||
int32_t i);
|
||||
extern void json_object_long_add(struct json_object* obj, const char *key,
|
||||
int64_t i);
|
||||
extern void json_object_boolean_false_add(struct json_object* obj,
|
||||
const char *key);
|
||||
extern void json_object_boolean_true_add(struct json_object* obj,
|
||||
|
@ -444,7 +444,7 @@ void ospf6_spf_reason_string (unsigned int reason, char *buf, int size)
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
for (bit = 0; bit <= (sizeof(ospf6_spf_reason_str) / sizeof(char *)); bit++)
|
||||
for (bit = 0; bit < array_size(ospf6_spf_reason_str); bit++)
|
||||
{
|
||||
if ((reason & (1 << bit)) && (len < size))
|
||||
{
|
||||
|
@ -155,6 +155,8 @@ ospf6_create (void)
|
||||
|
||||
o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
|
||||
|
||||
o->distance_table = route_table_init ();
|
||||
|
||||
/* Enable "log-adjacency-changes" */
|
||||
SET_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
|
||||
|
||||
@ -184,6 +186,9 @@ ospf6_delete (struct ospf6 *o)
|
||||
ospf6_route_table_delete (o->external_table);
|
||||
route_table_finish (o->external_id_table);
|
||||
|
||||
ospf6_distance_reset (o);
|
||||
route_table_finish (o->distance_table);
|
||||
|
||||
XFREE (MTYPE_OSPF6_TOP, o);
|
||||
}
|
||||
|
||||
@ -448,6 +453,213 @@ DEFUN (no_ospf6_timers_lsa,
|
||||
}
|
||||
|
||||
|
||||
DEFUN (ospf6_distance,
|
||||
ospf6_distance_cmd,
|
||||
"distance (1-255)",
|
||||
"Administrative distance\n"
|
||||
"OSPF6 Administrative distance\n")
|
||||
{
|
||||
struct ospf6 *o = vty->index;
|
||||
|
||||
o->distance_all = atoi (argv[1]->arg);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_ospf6_distance,
|
||||
no_ospf6_distance_cmd,
|
||||
"no distance (1-255)",
|
||||
NO_STR
|
||||
"Administrative distance\n"
|
||||
"OSPF6 Administrative distance\n")
|
||||
{
|
||||
struct ospf6 *o = vty->index;
|
||||
|
||||
o->distance_all = 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (ospf6_distance_ospf6,
|
||||
ospf6_distance_ospf6_cmd,
|
||||
"distance ospf6 <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)>",
|
||||
"Administrative distance\n"
|
||||
"OSPF6 distance\n"
|
||||
"Intra-area routes\n"
|
||||
"Distance for intra-area routes\n"
|
||||
"Inter-area routes\n"
|
||||
"Distance for inter-area routes\n"
|
||||
"External routes\n"
|
||||
"Distance for external routes\n"
|
||||
"Intra-area routes\n"
|
||||
"Distance for intra-area routes\n"
|
||||
"Inter-area routes\n"
|
||||
"Distance for inter-area routes\n"
|
||||
"External routes\n"
|
||||
"Distance for external routes\n"
|
||||
"Intra-area routes\n"
|
||||
"Distance for intra-area routes\n"
|
||||
"Inter-area routes\n"
|
||||
"Distance for inter-area routes\n"
|
||||
"External routes\n"
|
||||
"Distance for external routes\n")
|
||||
{
|
||||
struct ospf6 *o = vty->index;
|
||||
|
||||
char *intra, *inter, *external;
|
||||
intra = inter = external = NULL;
|
||||
|
||||
int idx = 0;
|
||||
if (argv_find (argv, argc, "intra-area", &idx))
|
||||
intra = argv[++idx]->arg;
|
||||
if (argv_find (argv, argc, "intra-area", &idx))
|
||||
{
|
||||
vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
if (argv_find (argv, argc, "inter-area", &idx))
|
||||
inter = argv[++idx]->arg;
|
||||
if (argv_find (argv, argc, "inter-area", &idx))
|
||||
{
|
||||
vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
if (argv_find (argv, argc, "external", &idx))
|
||||
external = argv[++idx]->arg;
|
||||
if (argv_find (argv, argc, "external", &idx))
|
||||
{
|
||||
vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
|
||||
if (intra)
|
||||
o->distance_intra = atoi (intra);
|
||||
|
||||
if (inter)
|
||||
o->distance_inter = atoi (inter);
|
||||
|
||||
if (external)
|
||||
o->distance_external = atoi (external);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_ospf6_distance_ospf6,
|
||||
no_ospf6_distance_ospf6_cmd,
|
||||
"no distance ospf6 [<intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)>]",
|
||||
NO_STR
|
||||
"Administrative distance\n"
|
||||
"OSPF6 distance\n"
|
||||
"Intra-area routes\n"
|
||||
"Distance for intra-area routes\n"
|
||||
"Inter-area routes\n"
|
||||
"Distance for inter-area routes\n"
|
||||
"External routes\n"
|
||||
"Distance for external routes\n"
|
||||
"Intra-area routes\n"
|
||||
"Distance for intra-area routes\n"
|
||||
"Inter-area routes\n"
|
||||
"Distance for inter-area routes\n"
|
||||
"External routes\n"
|
||||
"Distance for external routes\n"
|
||||
"Intra-area routes\n"
|
||||
"Distance for intra-area routes\n"
|
||||
"Inter-area routes\n"
|
||||
"Distance for inter-area routes\n"
|
||||
"External routes\n"
|
||||
"Distance for external routes\n")
|
||||
{
|
||||
struct ospf6 *o = vty->index;
|
||||
|
||||
char *intra, *inter, *external;
|
||||
intra = inter = external = NULL;
|
||||
|
||||
if (argc == 3)
|
||||
{
|
||||
/* If no arguments are given, clear all distance information */
|
||||
o->distance_intra = 0;
|
||||
o->distance_inter = 0;
|
||||
o->distance_external = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
if (argv_find (argv, argc, "intra-area", &idx))
|
||||
intra = argv[++idx]->arg;
|
||||
if (argv_find (argv, argc, "intra-area", &idx))
|
||||
{
|
||||
vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
if (argv_find (argv, argc, "inter-area", &idx))
|
||||
inter = argv[++idx]->arg;
|
||||
if (argv_find (argv, argc, "inter-area", &idx))
|
||||
{
|
||||
vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
if (argv_find (argv, argc, "external", &idx))
|
||||
external = argv[++idx]->arg;
|
||||
if (argv_find (argv, argc, "external", &idx))
|
||||
{
|
||||
vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (argc < 3) /* should not happen */
|
||||
return CMD_WARNING;
|
||||
|
||||
if (intra)
|
||||
o->distance_intra = 0;
|
||||
|
||||
if (inter)
|
||||
o->distance_inter = 0;
|
||||
|
||||
if (external)
|
||||
o->distance_external = 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (ospf6_distance_source,
|
||||
ospf6_distance_source_cmd,
|
||||
"distance (1-255) X:X::X:X/M [WORD]",
|
||||
"Administrative distance\n"
|
||||
"Distance value\n"
|
||||
"IP source prefix\n"
|
||||
"Access list name\n")
|
||||
{
|
||||
struct ospf6 *o = vty->index;
|
||||
char *alname = (argc == 4) ? argv[3]->arg : NULL;
|
||||
ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_ospf6_distance_source,
|
||||
no_ospf6_distance_source_cmd,
|
||||
"no distance (1-255) X:X::X:X/M [WORD]",
|
||||
NO_STR
|
||||
"Administrative distance\n"
|
||||
"Distance value\n"
|
||||
"IP source prefix\n"
|
||||
"Access list name\n")
|
||||
{
|
||||
struct ospf6 *o = vty->index;
|
||||
char *alname = (argc == 5) ? argv[4]->arg : NULL;
|
||||
ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (ospf6_interface_area,
|
||||
ospf6_interface_area_cmd,
|
||||
"interface IFNAME area A.B.C.D",
|
||||
@ -855,6 +1067,44 @@ ospf6_stub_router_config_write (struct vty *vty)
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
ospf6_distance_config_write (struct vty *vty)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct ospf6_distance *odistance;
|
||||
|
||||
if (ospf6->distance_all)
|
||||
vty_out (vty, " distance %u%s", ospf6->distance_all, VTY_NEWLINE);
|
||||
|
||||
if (ospf6->distance_intra
|
||||
|| ospf6->distance_inter
|
||||
|| ospf6->distance_external)
|
||||
{
|
||||
vty_out (vty, " distance ospf6");
|
||||
|
||||
if (ospf6->distance_intra)
|
||||
vty_out (vty, " intra-area %u", ospf6->distance_intra);
|
||||
if (ospf6->distance_inter)
|
||||
vty_out (vty, " inter-area %u", ospf6->distance_inter);
|
||||
if (ospf6->distance_external)
|
||||
vty_out (vty, " external %u", ospf6->distance_external);
|
||||
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
for (rn = route_top (ospf6->distance_table); rn; rn = route_next (rn))
|
||||
if ((odistance = rn->info) != NULL)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
|
||||
vty_out (vty, " distance %u %s %s%s", odistance->distance,
|
||||
prefix2str (&rn->p, buf, sizeof (buf)),
|
||||
odistance->access_list ? odistance->access_list : "",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OSPF configuration write function. */
|
||||
static int
|
||||
config_write_ospf6 (struct vty *vty)
|
||||
@ -897,6 +1147,7 @@ config_write_ospf6 (struct vty *vty)
|
||||
ospf6_redistribute_config_write (vty);
|
||||
ospf6_area_config_write (vty);
|
||||
ospf6_spf_config_write (vty);
|
||||
ospf6_distance_config_write (vty);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, j, oa))
|
||||
{
|
||||
@ -953,6 +1204,13 @@ ospf6_top_init (void)
|
||||
install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
|
||||
install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
|
||||
*/
|
||||
|
||||
install_element (OSPF6_NODE, &ospf6_distance_cmd);
|
||||
install_element (OSPF6_NODE, &no_ospf6_distance_cmd);
|
||||
install_element (OSPF6_NODE, &ospf6_distance_ospf6_cmd);
|
||||
install_element (OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
|
||||
#if 0
|
||||
install_element (OSPF6_NODE, &ospf6_distance_source_cmd);
|
||||
install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,6 +85,14 @@ struct ospf6
|
||||
struct thread *maxage_remover;
|
||||
|
||||
u_int32_t ref_bandwidth;
|
||||
|
||||
/* Distance parameters */
|
||||
u_char distance_all;
|
||||
u_char distance_intra;
|
||||
u_char distance_inter;
|
||||
u_char distance_external;
|
||||
|
||||
struct route_table *distance_table;
|
||||
};
|
||||
|
||||
#define OSPF6_DISABLED 0x01
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "ospf6_zebra.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
|
||||
|
||||
unsigned char conf_debug_ospf6_zebra = 0;
|
||||
|
||||
/* information about zebra. */
|
||||
@ -456,6 +458,10 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
|
||||
}
|
||||
|
||||
dest = (struct prefix_ipv6 *) &request->prefix;
|
||||
|
||||
SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
|
||||
api.distance = ospf6_distance_apply (dest, request);
|
||||
|
||||
if (type == REM)
|
||||
ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api);
|
||||
else
|
||||
@ -640,6 +646,150 @@ DEFUN (no_redistribute_ospf6,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct ospf6_distance *
|
||||
ospf6_distance_new (void)
|
||||
{
|
||||
return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance));
|
||||
}
|
||||
|
||||
static void
|
||||
ospf6_distance_free (struct ospf6_distance *odistance)
|
||||
{
|
||||
XFREE (MTYPE_OSPF6_DISTANCE, odistance);
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_distance_set (struct vty *vty, struct ospf6 *o,
|
||||
const char *distance_str,
|
||||
const char *ip_str,
|
||||
const char *access_list_str)
|
||||
{
|
||||
int ret;
|
||||
struct prefix_ipv6 p;
|
||||
u_char distance;
|
||||
struct route_node *rn;
|
||||
struct ospf6_distance *odistance;
|
||||
|
||||
ret = str2prefix_ipv6 (ip_str, &p);
|
||||
if (ret == 0)
|
||||
{
|
||||
vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
distance = atoi (distance_str);
|
||||
|
||||
/* Get OSPF6 distance node. */
|
||||
rn = route_node_get (o->distance_table, (struct prefix *) &p);
|
||||
if (rn->info)
|
||||
{
|
||||
odistance = rn->info;
|
||||
route_unlock_node (rn);
|
||||
}
|
||||
else
|
||||
{
|
||||
odistance = ospf6_distance_new ();
|
||||
rn->info = odistance;
|
||||
}
|
||||
|
||||
/* Set distance value. */
|
||||
odistance->distance = distance;
|
||||
|
||||
/* Reset access-list configuration. */
|
||||
if (odistance->access_list)
|
||||
{
|
||||
free (odistance->access_list);
|
||||
odistance->access_list = NULL;
|
||||
}
|
||||
if (access_list_str)
|
||||
odistance->access_list = strdup (access_list_str);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_distance_unset (struct vty *vty, struct ospf6 *o,
|
||||
const char *distance_str,
|
||||
const char *ip_str,
|
||||
const char *access_list_str)
|
||||
{
|
||||
int ret;
|
||||
struct prefix_ipv6 p;
|
||||
struct route_node *rn;
|
||||
struct ospf6_distance *odistance;
|
||||
|
||||
ret = str2prefix_ipv6 (ip_str, &p);
|
||||
if (ret == 0)
|
||||
{
|
||||
vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
rn = route_node_lookup (o->distance_table, (struct prefix *) &p);
|
||||
if (!rn)
|
||||
{
|
||||
vty_out (vty, "Cant't find specified prefix%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
odistance = rn->info;
|
||||
|
||||
if (odistance->access_list)
|
||||
free (odistance->access_list);
|
||||
ospf6_distance_free (odistance);
|
||||
|
||||
rn->info = NULL;
|
||||
route_unlock_node (rn);
|
||||
route_unlock_node (rn);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_distance_reset (struct ospf6 *o)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct ospf6_distance *odistance;
|
||||
|
||||
for (rn = route_top (o->distance_table); rn; rn = route_next (rn))
|
||||
if ((odistance = rn->info) != NULL)
|
||||
{
|
||||
if (odistance->access_list)
|
||||
free (odistance->access_list);
|
||||
ospf6_distance_free (odistance);
|
||||
rn->info = NULL;
|
||||
route_unlock_node (rn);
|
||||
}
|
||||
}
|
||||
|
||||
u_char
|
||||
ospf6_distance_apply (struct prefix_ipv6 *p, struct ospf6_route *or)
|
||||
{
|
||||
struct ospf6 *o;
|
||||
|
||||
o = ospf6;
|
||||
if (o == NULL)
|
||||
return 0;
|
||||
|
||||
if (o->distance_intra)
|
||||
if (or->path.type == OSPF6_PATH_TYPE_INTRA)
|
||||
return o->distance_intra;
|
||||
|
||||
if (o->distance_inter)
|
||||
if (or->path.type == OSPF6_PATH_TYPE_INTER)
|
||||
return o->distance_inter;
|
||||
|
||||
if (o->distance_external)
|
||||
if(or->path.type == OSPF6_PATH_TYPE_EXTERNAL1
|
||||
|| or->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
|
||||
return o->distance_external;
|
||||
|
||||
if (o->distance_all)
|
||||
return o->distance_all;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ospf6_zebra_connected (struct zclient *zclient)
|
||||
{
|
||||
|
@ -35,6 +35,16 @@ extern unsigned char conf_debug_ospf6_zebra;
|
||||
#define IS_OSPF6_DEBUG_ZEBRA(e) \
|
||||
(conf_debug_ospf6_zebra & OSPF6_DEBUG_ZEBRA_ ## e)
|
||||
|
||||
/* OSPF6 distance */
|
||||
struct ospf6_distance
|
||||
{
|
||||
/* Distance value for the IP source prefix */
|
||||
u_char distance;
|
||||
|
||||
/* Name of the access-list to be matched */
|
||||
char *access_list;
|
||||
};
|
||||
|
||||
extern struct zclient *zclient;
|
||||
|
||||
extern void ospf6_zebra_route_update_add (struct ospf6_route *request);
|
||||
@ -48,6 +58,15 @@ extern void ospf6_zebra_init (struct thread_master *);
|
||||
extern void ospf6_zebra_add_discard (struct ospf6_route *request);
|
||||
extern void ospf6_zebra_delete_discard (struct ospf6_route *request);
|
||||
|
||||
struct ospf6;
|
||||
extern void ospf6_distance_reset (struct ospf6 *);
|
||||
extern u_char ospf6_distance_apply (struct prefix_ipv6 *, struct ospf6_route *);
|
||||
|
||||
extern int ospf6_distance_set (struct vty *, struct ospf6 *, const char *,
|
||||
const char *, const char *);
|
||||
extern int ospf6_distance_unset (struct vty *, struct ospf6 *, const char *,
|
||||
const char *, const char *);
|
||||
|
||||
extern int config_write_ospf6_debug_zebra (struct vty *vty);
|
||||
extern void install_element_ospf6_debug_zebra (void);
|
||||
|
||||
|
@ -946,7 +946,7 @@ static int
|
||||
ospf_vl_set_timers (struct ospf_vl_data *vl_data,
|
||||
struct ospf_vl_config_data *vl_config)
|
||||
{
|
||||
struct interface *ifp = ifp = vl_data->vl_oi->ifp;
|
||||
struct interface *ifp = vl_data->vl_oi->ifp;
|
||||
/* Virtual Link data initialised to defaults, so only set
|
||||
if a value given */
|
||||
if (vl_config->hello_interval)
|
||||
|
@ -198,6 +198,10 @@ int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr
|
||||
pim_static_route_free(s_route);
|
||||
}
|
||||
|
||||
if (original_s_route) {
|
||||
pim_static_route_free(original_s_route);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -748,9 +748,9 @@ rip_packet_dump (struct rip_packet *packet, int size, const char *sndrcv)
|
||||
zlog_debug (" family 0x%X type %d (MD5 data)",
|
||||
ntohs (rte->family), ntohs (rte->tag));
|
||||
zlog_debug (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
|
||||
"%02X%02X%02X%02X%02X%02X%02X",
|
||||
"%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6],
|
||||
p[7], p[9], p[10], p[11], p[12], p[13],
|
||||
p[7], p[8], p[9], p[10], p[11], p[12], p[13],
|
||||
p[14], p[15]);
|
||||
}
|
||||
else
|
||||
|
@ -185,7 +185,8 @@ vtysh_client_run (struct vtysh_client *vclient, const char *line, FILE *fp)
|
||||
|
||||
memmove (buf, eol, bufvalid - eol);
|
||||
bufvalid -= eol - buf;
|
||||
end -= eol - buf;
|
||||
if (end)
|
||||
end -= eol - buf;
|
||||
}
|
||||
|
||||
if (bufvalid == buf + bufsz)
|
||||
|
Loading…
Reference in New Issue
Block a user