mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 22:29:23 +00:00
Merge pull request #1056 from opensourcerouting/oldbits-0
"pathspace" options, vtysh-suid-cleanups, "vty_frame()"
This commit is contained in:
commit
32592ffb4f
@ -1321,7 +1321,7 @@ interface_config_write (struct vty *vty)
|
|||||||
int write = 0;
|
int write = 0;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
||||||
vty_out (vty, "interface %s\n",ifp->name);
|
vty_frame (vty, "interface %s\n",ifp->name);
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out (vty, " description %s\n",ifp->desc);
|
vty_out (vty, " description %s\n",ifp->desc);
|
||||||
babel_interface_nfo *babel_ifp = babel_get_if_nfo (ifp);
|
babel_interface_nfo *babel_ifp = babel_get_if_nfo (ifp);
|
||||||
@ -1377,7 +1377,7 @@ interface_config_write (struct vty *vty)
|
|||||||
write++;
|
write++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vty_out (vty, "!\n");
|
vty_endframe (vty, "!\n");
|
||||||
write++;
|
write++;
|
||||||
}
|
}
|
||||||
return write;
|
return write;
|
||||||
|
@ -50,11 +50,6 @@ struct vni_walk_ctx {
|
|||||||
json_object *json;
|
json_object *json;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct evpn_config_write {
|
|
||||||
int write;
|
|
||||||
struct vty *vty;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(HAVE_CUMULUS)
|
#if defined(HAVE_CUMULUS)
|
||||||
static void display_import_rt(struct vty *vty, struct irt_node *irt,
|
static void display_import_rt(struct vty *vty, struct irt_node *irt,
|
||||||
json_object *json)
|
json_object *json)
|
||||||
@ -587,155 +582,150 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
|
if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((table = rn->info) != NULL) {
|
if ((table = rn->info) == NULL)
|
||||||
rd_header = 1;
|
continue;
|
||||||
|
|
||||||
for (rm = bgp_table_top(table); rm;
|
rd_header = 1;
|
||||||
rm = bgp_route_next(rm))
|
|
||||||
for (ri = rm->info; ri; ri = ri->next) {
|
|
||||||
total_count++;
|
|
||||||
if (type == bgp_show_type_neighbor) {
|
|
||||||
union sockunion *su =
|
|
||||||
output_arg;
|
|
||||||
|
|
||||||
if (ri->peer->su_remote == NULL
|
for (rm = bgp_table_top(table); rm;
|
||||||
|| !sockunion_same(
|
rm = bgp_route_next(rm))
|
||||||
ri->peer->su_remote,
|
for (ri = rm->info; ri; ri = ri->next) {
|
||||||
su))
|
total_count++;
|
||||||
continue;
|
if (type == bgp_show_type_neighbor) {
|
||||||
}
|
union sockunion *su =
|
||||||
if (header == 0) {
|
output_arg;
|
||||||
if (use_json) {
|
|
||||||
if (option
|
|
||||||
== SHOW_DISPLAY_TAGS) {
|
|
||||||
json_object_int_add(
|
|
||||||
json,
|
|
||||||
"bgpTableVersion",
|
|
||||||
0);
|
|
||||||
json_object_string_add(
|
|
||||||
json,
|
|
||||||
"bgpLocalRouterId",
|
|
||||||
inet_ntoa(
|
|
||||||
bgp->router_id));
|
|
||||||
json_object_object_add(
|
|
||||||
json,
|
|
||||||
"bgpStatusCodes",
|
|
||||||
json_scode);
|
|
||||||
json_object_object_add(
|
|
||||||
json,
|
|
||||||
"bgpOriginCodes",
|
|
||||||
json_ocode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (option
|
|
||||||
== SHOW_DISPLAY_TAGS)
|
|
||||||
vty_out(vty,
|
|
||||||
V4_HEADER_TAG);
|
|
||||||
else if (
|
|
||||||
option
|
|
||||||
== SHOW_DISPLAY_OVERLAY)
|
|
||||||
vty_out(vty,
|
|
||||||
V4_HEADER_OVERLAY);
|
|
||||||
else {
|
|
||||||
vty_out(vty,
|
|
||||||
"BGP table version is 0, local router ID is %s\n",
|
|
||||||
inet_ntoa(
|
|
||||||
bgp->router_id));
|
|
||||||
vty_out(vty,
|
|
||||||
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
|
|
||||||
vty_out(vty,
|
|
||||||
"Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
|
|
||||||
vty_out(vty,
|
|
||||||
V4_HEADER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
header = 0;
|
|
||||||
}
|
|
||||||
if (rd_header) {
|
|
||||||
u_int16_t type;
|
|
||||||
struct rd_as rd_as;
|
|
||||||
struct rd_ip rd_ip;
|
|
||||||
u_char *pnt;
|
|
||||||
|
|
||||||
pnt = rn->p.u.val;
|
if (ri->peer->su_remote == NULL
|
||||||
|
|| !sockunion_same(
|
||||||
/* Decode RD type. */
|
ri->peer->su_remote,
|
||||||
type = decode_rd_type(pnt);
|
su))
|
||||||
/* Decode RD value. */
|
continue;
|
||||||
if (type == RD_TYPE_AS)
|
|
||||||
decode_rd_as(pnt + 2,
|
|
||||||
&rd_as);
|
|
||||||
else if (type == RD_TYPE_AS4)
|
|
||||||
decode_rd_as4(pnt + 2,
|
|
||||||
&rd_as);
|
|
||||||
else if (type == RD_TYPE_IP)
|
|
||||||
decode_rd_ip(pnt + 2,
|
|
||||||
&rd_ip);
|
|
||||||
if (use_json) {
|
|
||||||
char buffer[BUFSIZ];
|
|
||||||
if (type == RD_TYPE_AS
|
|
||||||
|| type == RD_TYPE_AS4)
|
|
||||||
sprintf(buffer,
|
|
||||||
"%u:%d",
|
|
||||||
rd_as.as,
|
|
||||||
rd_as.val);
|
|
||||||
else if (type
|
|
||||||
== RD_TYPE_IP)
|
|
||||||
sprintf(buffer,
|
|
||||||
"%s:%d",
|
|
||||||
inet_ntoa(
|
|
||||||
rd_ip.ip),
|
|
||||||
rd_ip.val);
|
|
||||||
json_object_string_add(
|
|
||||||
json_nroute,
|
|
||||||
"routeDistinguisher",
|
|
||||||
buffer);
|
|
||||||
} else {
|
|
||||||
vty_out(vty,
|
|
||||||
"Route Distinguisher: ");
|
|
||||||
if (type == RD_TYPE_AS)
|
|
||||||
vty_out(vty,
|
|
||||||
"as2 %u:%d",
|
|
||||||
rd_as.as,
|
|
||||||
rd_as.val);
|
|
||||||
else if (type
|
|
||||||
== RD_TYPE_AS4)
|
|
||||||
vty_out(vty,
|
|
||||||
"as4 %u:%d",
|
|
||||||
rd_as.as,
|
|
||||||
rd_as.val);
|
|
||||||
else if (type
|
|
||||||
== RD_TYPE_IP)
|
|
||||||
vty_out(vty,
|
|
||||||
"ip %s:%d",
|
|
||||||
inet_ntoa(
|
|
||||||
rd_ip.ip),
|
|
||||||
rd_ip.val);
|
|
||||||
vty_out(vty, "\n\n");
|
|
||||||
}
|
|
||||||
rd_header = 0;
|
|
||||||
}
|
|
||||||
if (use_json)
|
|
||||||
json_array =
|
|
||||||
json_object_new_array();
|
|
||||||
else
|
|
||||||
json_array = NULL;
|
|
||||||
if (option == SHOW_DISPLAY_TAGS)
|
|
||||||
route_vty_out_tag(
|
|
||||||
vty, &rm->p, ri, 0,
|
|
||||||
SAFI_EVPN, json_array);
|
|
||||||
else if (option == SHOW_DISPLAY_OVERLAY)
|
|
||||||
route_vty_out_overlay(
|
|
||||||
vty, &rm->p, ri, 0,
|
|
||||||
json_array);
|
|
||||||
else
|
|
||||||
route_vty_out(vty, &rm->p, ri,
|
|
||||||
0, SAFI_EVPN,
|
|
||||||
json_array);
|
|
||||||
output_count++;
|
|
||||||
}
|
}
|
||||||
/* XXX json */
|
if (header == 0) {
|
||||||
}
|
if (use_json) {
|
||||||
|
if (option
|
||||||
|
== SHOW_DISPLAY_TAGS) {
|
||||||
|
json_object_int_add(
|
||||||
|
json,
|
||||||
|
"bgpTableVersion",
|
||||||
|
0);
|
||||||
|
json_object_string_add(
|
||||||
|
json,
|
||||||
|
"bgpLocalRouterId",
|
||||||
|
inet_ntoa(
|
||||||
|
bgp->router_id));
|
||||||
|
json_object_object_add(
|
||||||
|
json,
|
||||||
|
"bgpStatusCodes",
|
||||||
|
json_scode);
|
||||||
|
json_object_object_add(
|
||||||
|
json,
|
||||||
|
"bgpOriginCodes",
|
||||||
|
json_ocode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (option
|
||||||
|
== SHOW_DISPLAY_TAGS)
|
||||||
|
vty_out(vty,
|
||||||
|
V4_HEADER_TAG);
|
||||||
|
else if (
|
||||||
|
option
|
||||||
|
== SHOW_DISPLAY_OVERLAY)
|
||||||
|
vty_out(vty,
|
||||||
|
V4_HEADER_OVERLAY);
|
||||||
|
else {
|
||||||
|
vty_out(vty,
|
||||||
|
"BGP table version is 0, local router ID is %s\n",
|
||||||
|
inet_ntoa(
|
||||||
|
bgp->router_id));
|
||||||
|
vty_out(vty,
|
||||||
|
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
|
||||||
|
vty_out(vty,
|
||||||
|
"Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
|
||||||
|
vty_out(vty,
|
||||||
|
V4_HEADER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header = 0;
|
||||||
|
}
|
||||||
|
if (rd_header) {
|
||||||
|
u_int16_t type;
|
||||||
|
struct rd_as rd_as;
|
||||||
|
struct rd_ip rd_ip;
|
||||||
|
u_char *pnt;
|
||||||
|
|
||||||
|
pnt = rn->p.u.val;
|
||||||
|
|
||||||
|
/* Decode RD type. */
|
||||||
|
type = decode_rd_type(pnt);
|
||||||
|
/* Decode RD value. */
|
||||||
|
if (type == RD_TYPE_AS)
|
||||||
|
decode_rd_as(pnt + 2, &rd_as);
|
||||||
|
else if (type == RD_TYPE_AS4)
|
||||||
|
decode_rd_as4(pnt + 2, &rd_as);
|
||||||
|
else if (type == RD_TYPE_IP)
|
||||||
|
decode_rd_ip(pnt + 2, &rd_ip);
|
||||||
|
if (use_json) {
|
||||||
|
char buffer[BUFSIZ];
|
||||||
|
if (type == RD_TYPE_AS
|
||||||
|
|| type == RD_TYPE_AS4)
|
||||||
|
sprintf(buffer,
|
||||||
|
"%u:%d",
|
||||||
|
rd_as.as,
|
||||||
|
rd_as.val);
|
||||||
|
else if (type
|
||||||
|
== RD_TYPE_IP)
|
||||||
|
sprintf(buffer,
|
||||||
|
"%s:%d",
|
||||||
|
inet_ntoa(
|
||||||
|
rd_ip.ip),
|
||||||
|
rd_ip.val);
|
||||||
|
json_object_string_add(
|
||||||
|
json_nroute,
|
||||||
|
"routeDistinguisher",
|
||||||
|
buffer);
|
||||||
|
} else {
|
||||||
|
vty_out(vty,
|
||||||
|
"Route Distinguisher: ");
|
||||||
|
if (type == RD_TYPE_AS)
|
||||||
|
vty_out(vty,
|
||||||
|
"as2 %u:%d",
|
||||||
|
rd_as.as,
|
||||||
|
rd_as.val);
|
||||||
|
else if (type
|
||||||
|
== RD_TYPE_AS4)
|
||||||
|
vty_out(vty,
|
||||||
|
"as4 %u:%d",
|
||||||
|
rd_as.as,
|
||||||
|
rd_as.val);
|
||||||
|
else if (type
|
||||||
|
== RD_TYPE_IP)
|
||||||
|
vty_out(vty,
|
||||||
|
"ip %s:%d",
|
||||||
|
inet_ntoa(
|
||||||
|
rd_ip.ip),
|
||||||
|
rd_ip.val);
|
||||||
|
vty_out(vty, "\n\n");
|
||||||
|
}
|
||||||
|
rd_header = 0;
|
||||||
|
}
|
||||||
|
if (use_json)
|
||||||
|
json_array = json_object_new_array();
|
||||||
|
else
|
||||||
|
json_array = NULL;
|
||||||
|
if (option == SHOW_DISPLAY_TAGS)
|
||||||
|
route_vty_out_tag(vty, &rm->p, ri, 0,
|
||||||
|
SAFI_EVPN,
|
||||||
|
json_array);
|
||||||
|
else if (option == SHOW_DISPLAY_OVERLAY)
|
||||||
|
route_vty_out_overlay(vty, &rm->p, ri,
|
||||||
|
0, json_array);
|
||||||
|
else
|
||||||
|
route_vty_out(vty, &rm->p, ri, 0,
|
||||||
|
SAFI_EVPN, json_array);
|
||||||
|
output_count++;
|
||||||
|
}
|
||||||
|
/* XXX json */
|
||||||
}
|
}
|
||||||
if (output_count == 0)
|
if (output_count == 0)
|
||||||
vty_out(vty, "No prefixes displayed, %ld exist\n", total_count);
|
vty_out(vty, "No prefixes displayed, %ld exist\n", total_count);
|
||||||
@ -2125,17 +2115,14 @@ static void evpn_unset_advertise_all_vni(struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_CUMULUS */
|
#endif /* HAVE_CUMULUS */
|
||||||
|
|
||||||
static void write_vni_config(struct vty *vty, struct bgpevpn *vpn, int *write)
|
static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
|
||||||
{
|
{
|
||||||
char buf1[INET6_ADDRSTRLEN];
|
char buf1[INET6_ADDRSTRLEN];
|
||||||
afi_t afi = AFI_L2VPN;
|
|
||||||
safi_t safi = SAFI_EVPN;
|
|
||||||
char *ecom_str;
|
char *ecom_str;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct ecommunity *ecom;
|
struct ecommunity *ecom;
|
||||||
|
|
||||||
if (is_vni_configured(vpn)) {
|
if (is_vni_configured(vpn)) {
|
||||||
bgp_config_write_family_header(vty, afi, safi, write);
|
|
||||||
vty_out(vty, " vni %d\n", vpn->vni);
|
vty_out(vty, " vni %d\n", vpn->vni);
|
||||||
if (is_rd_configured(vpn))
|
if (is_rd_configured(vpn))
|
||||||
vty_out(vty, " rd %s\n",
|
vty_out(vty, " rd %s\n",
|
||||||
@ -2171,10 +2158,10 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn, int *write)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void write_vni_config_for_entry(struct hash_backet *backet,
|
static void write_vni_config_for_entry(struct hash_backet *backet,
|
||||||
struct evpn_config_write *cfg)
|
struct vty *vty)
|
||||||
{
|
{
|
||||||
struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
|
struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
|
||||||
write_vni_config(cfg->vty, vpn, &cfg->write);
|
write_vni_config(vty, vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CUMULUS)
|
#if defined(HAVE_CUMULUS)
|
||||||
@ -3326,29 +3313,19 @@ DEFUN (no_bgp_evpn_vni_rt_without_val,
|
|||||||
* Output EVPN configuration information.
|
* Output EVPN configuration information.
|
||||||
*/
|
*/
|
||||||
void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
|
void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
|
||||||
safi_t safi, int *write)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
struct evpn_config_write cfg;
|
if (bgp->vnihash)
|
||||||
|
|
||||||
if (bgp->vnihash) {
|
|
||||||
cfg.write = *write;
|
|
||||||
cfg.vty = vty;
|
|
||||||
hash_iterate(bgp->vnihash,
|
hash_iterate(bgp->vnihash,
|
||||||
(void (*)(struct hash_backet *,
|
(void (*)(struct hash_backet *,
|
||||||
void *))write_vni_config_for_entry,
|
void *))write_vni_config_for_entry,
|
||||||
&cfg);
|
vty);
|
||||||
*write = cfg.write;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bgp->advertise_all_vni) {
|
if (bgp->advertise_all_vni)
|
||||||
bgp_config_write_family_header(vty, afi, safi, write);
|
|
||||||
vty_out(vty, " advertise-all-vni\n");
|
vty_out(vty, " advertise-all-vni\n");
|
||||||
}
|
|
||||||
|
|
||||||
if (bgp->advertise_gw_macip) {
|
if (bgp->advertise_gw_macip)
|
||||||
bgp_config_write_family_header(vty, afi, safi, write);
|
|
||||||
vty_out(vty, " advertise-default-gw\n");
|
vty_out(vty, " advertise-default-gw\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_ethernetvpn_init(void)
|
void bgp_ethernetvpn_init(void)
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#define _FRR_BGP_EVPN_VTY_H
|
#define _FRR_BGP_EVPN_VTY_H
|
||||||
|
|
||||||
extern void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp,
|
extern void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp,
|
||||||
afi_t afi, safi_t safi, int *write);
|
afi_t afi, safi_t safi);
|
||||||
extern void bgp_ethernetvpn_init(void);
|
extern void bgp_ethernetvpn_init(void);
|
||||||
|
|
||||||
#define L2VPN_HELP_STR "Layer 2 Virtual Private Network\n"
|
#define L2VPN_HELP_STR "Layer 2 Virtual Private Network\n"
|
||||||
|
955
bgpd/bgp_route.c
955
bgpd/bgp_route.c
File diff suppressed because it is too large
Load Diff
@ -369,12 +369,9 @@ extern void bgp_process(struct bgp *, struct bgp_node *, afi_t, safi_t);
|
|||||||
* queue element with NULL bgp node.
|
* queue element with NULL bgp node.
|
||||||
*/
|
*/
|
||||||
extern void bgp_add_eoiu_mark(struct bgp *);
|
extern void bgp_add_eoiu_mark(struct bgp *);
|
||||||
extern int bgp_config_write_table_map(struct vty *, struct bgp *, afi_t, safi_t,
|
extern void bgp_config_write_table_map(struct vty *, struct bgp *, afi_t, safi_t);
|
||||||
int *);
|
extern void bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t);
|
||||||
extern int bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t,
|
extern void bgp_config_write_distance(struct vty *, struct bgp *, afi_t, safi_t);
|
||||||
int *);
|
|
||||||
extern int bgp_config_write_distance(struct vty *, struct bgp *, afi_t, safi_t,
|
|
||||||
int *);
|
|
||||||
|
|
||||||
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
|
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
|
||||||
struct bgp_info *, afi_t, safi_t);
|
struct bgp_info *, afi_t, safi_t);
|
||||||
|
679
bgpd/bgp_vty.c
679
bgpd/bgp_vty.c
@ -1279,7 +1279,7 @@ static int bgp_update_delay_deconfig_vty(struct vty *vty)
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_config_write_update_delay(struct vty *vty, struct bgp *bgp)
|
void bgp_config_write_update_delay(struct vty *vty, struct bgp *bgp)
|
||||||
{
|
{
|
||||||
if (bgp->v_update_delay != BGP_UPDATE_DELAY_DEF) {
|
if (bgp->v_update_delay != BGP_UPDATE_DELAY_DEF) {
|
||||||
vty_out(vty, " update-delay %d", bgp->v_update_delay);
|
vty_out(vty, " update-delay %d", bgp->v_update_delay);
|
||||||
@ -1287,8 +1287,6 @@ int bgp_config_write_update_delay(struct vty *vty, struct bgp *bgp)
|
|||||||
vty_out(vty, " %d", bgp->v_establish_wait);
|
vty_out(vty, " %d", bgp->v_establish_wait);
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1342,12 +1340,10 @@ static int bgp_wpkt_quanta_config_vty(struct vty *vty, const char *num,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp)
|
void bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp)
|
||||||
{
|
{
|
||||||
if (bgp->wpkt_quanta != BGP_WRITE_PACKET_MAX)
|
if (bgp->wpkt_quanta != BGP_WRITE_PACKET_MAX)
|
||||||
vty_out(vty, " write-quanta %d\n", bgp->wpkt_quanta);
|
vty_out(vty, " write-quanta %d\n", bgp->wpkt_quanta);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1374,12 +1370,10 @@ DEFUN (no_bgp_wpkt_quanta,
|
|||||||
return bgp_wpkt_quanta_config_vty(vty, argv[idx_number]->arg, 0);
|
return bgp_wpkt_quanta_config_vty(vty, argv[idx_number]->arg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
|
void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
|
||||||
{
|
{
|
||||||
if (bgp->coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME)
|
if (bgp->coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME)
|
||||||
vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time);
|
vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1503,17 +1497,15 @@ ALIAS_HIDDEN(no_bgp_maxpaths_ibgp, no_bgp_maxpaths_ibgp_hidden_cmd,
|
|||||||
"Number of paths\n"
|
"Number of paths\n"
|
||||||
"Match the cluster length\n")
|
"Match the cluster length\n")
|
||||||
|
|
||||||
int bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, afi_t afi,
|
void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, afi_t afi,
|
||||||
safi_t safi, int *write)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
if (bgp->maxpaths[afi][safi].maxpaths_ebgp != MULTIPATH_NUM) {
|
if (bgp->maxpaths[afi][safi].maxpaths_ebgp != MULTIPATH_NUM) {
|
||||||
bgp_config_write_family_header(vty, afi, safi, write);
|
|
||||||
vty_out(vty, " maximum-paths %d\n",
|
vty_out(vty, " maximum-paths %d\n",
|
||||||
bgp->maxpaths[afi][safi].maxpaths_ebgp);
|
bgp->maxpaths[afi][safi].maxpaths_ebgp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bgp->maxpaths[afi][safi].maxpaths_ibgp != MULTIPATH_NUM) {
|
if (bgp->maxpaths[afi][safi].maxpaths_ibgp != MULTIPATH_NUM) {
|
||||||
bgp_config_write_family_header(vty, afi, safi, write);
|
|
||||||
vty_out(vty, " maximum-paths ibgp %d",
|
vty_out(vty, " maximum-paths ibgp %d",
|
||||||
bgp->maxpaths[afi][safi].maxpaths_ibgp);
|
bgp->maxpaths[afi][safi].maxpaths_ibgp);
|
||||||
if (CHECK_FLAG(bgp->maxpaths[afi][safi].ibgp_flags,
|
if (CHECK_FLAG(bgp->maxpaths[afi][safi].ibgp_flags,
|
||||||
@ -1521,8 +1513,6 @@ int bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
vty_out(vty, " equal-cluster-length");
|
vty_out(vty, " equal-cluster-length");
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BGP timers. */
|
/* BGP timers. */
|
||||||
@ -2459,7 +2449,7 @@ DEFUN (no_bgp_listen_range,
|
|||||||
return bgp_vty_return(vty, ret);
|
return bgp_vty_return(vty, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
|
void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
|
||||||
{
|
{
|
||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode, *rnode, *nrnode;
|
struct listnode *node, *nnode, *rnode, *nrnode;
|
||||||
@ -2482,8 +2472,6 @@ int bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6675,368 +6663,369 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
|
|||||||
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
|
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (peer->afc[afi][safi]) {
|
if (!peer->afc[afi][safi])
|
||||||
if (!count) {
|
continue;
|
||||||
unsigned long ents;
|
|
||||||
char memstrbuf[MTYPE_MEMSTR_LEN];
|
|
||||||
int vrf_id_ui;
|
|
||||||
|
|
||||||
vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
|
if (!count) {
|
||||||
? -1
|
unsigned long ents;
|
||||||
: bgp->vrf_id;
|
char memstrbuf[MTYPE_MEMSTR_LEN];
|
||||||
|
int vrf_id_ui;
|
||||||
|
|
||||||
/* Usage summary and header */
|
vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
|
||||||
|
? -1
|
||||||
|
: bgp->vrf_id;
|
||||||
|
|
||||||
|
/* Usage summary and header */
|
||||||
|
if (use_json) {
|
||||||
|
json_object_string_add(
|
||||||
|
json, "routerId",
|
||||||
|
inet_ntoa(bgp->router_id));
|
||||||
|
json_object_int_add(json, "as",
|
||||||
|
bgp->as);
|
||||||
|
json_object_int_add(json, "vrfId",
|
||||||
|
vrf_id_ui);
|
||||||
|
json_object_string_add(
|
||||||
|
json, "vrfName",
|
||||||
|
(bgp->inst_type
|
||||||
|
== BGP_INSTANCE_TYPE_DEFAULT)
|
||||||
|
? "Default"
|
||||||
|
: bgp->name);
|
||||||
|
} else {
|
||||||
|
vty_out(vty,
|
||||||
|
"BGP router identifier %s, local AS number %u vrf-id %d",
|
||||||
|
inet_ntoa(bgp->router_id),
|
||||||
|
bgp->as, vrf_id_ui);
|
||||||
|
vty_out(vty, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bgp_update_delay_configured(bgp)) {
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
json_object_string_add(
|
json_object_int_add(
|
||||||
json, "routerId",
|
json,
|
||||||
inet_ntoa(bgp->router_id));
|
"updateDelayLimit",
|
||||||
json_object_int_add(json, "as",
|
bgp->v_update_delay);
|
||||||
bgp->as);
|
|
||||||
json_object_int_add(json, "vrfId",
|
|
||||||
vrf_id_ui);
|
|
||||||
json_object_string_add(
|
|
||||||
json, "vrfName",
|
|
||||||
(bgp->inst_type
|
|
||||||
== BGP_INSTANCE_TYPE_DEFAULT)
|
|
||||||
? "Default"
|
|
||||||
: bgp->name);
|
|
||||||
} else {
|
|
||||||
vty_out(vty,
|
|
||||||
"BGP router identifier %s, local AS number %u vrf-id %d",
|
|
||||||
inet_ntoa(bgp->router_id),
|
|
||||||
bgp->as, vrf_id_ui);
|
|
||||||
vty_out(vty, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bgp_update_delay_configured(bgp)) {
|
if (bgp->v_update_delay
|
||||||
if (use_json) {
|
!= bgp->v_establish_wait)
|
||||||
json_object_int_add(
|
json_object_int_add(
|
||||||
json,
|
json,
|
||||||
"updateDelayLimit",
|
"updateDelayEstablishWait",
|
||||||
bgp->v_update_delay);
|
bgp->v_establish_wait);
|
||||||
|
|
||||||
if (bgp->v_update_delay
|
if (bgp_update_delay_active(
|
||||||
!= bgp->v_establish_wait)
|
bgp)) {
|
||||||
json_object_int_add(
|
json_object_string_add(
|
||||||
json,
|
json,
|
||||||
"updateDelayEstablishWait",
|
"updateDelayFirstNeighbor",
|
||||||
bgp->v_establish_wait);
|
bgp->update_delay_begin_time);
|
||||||
|
json_object_boolean_true_add(
|
||||||
if (bgp_update_delay_active(
|
json,
|
||||||
bgp)) {
|
"updateDelayInProgress");
|
||||||
|
} else {
|
||||||
|
if (bgp->update_delay_over) {
|
||||||
json_object_string_add(
|
json_object_string_add(
|
||||||
json,
|
json,
|
||||||
"updateDelayFirstNeighbor",
|
"updateDelayFirstNeighbor",
|
||||||
bgp->update_delay_begin_time);
|
bgp->update_delay_begin_time);
|
||||||
json_object_boolean_true_add(
|
json_object_string_add(
|
||||||
json,
|
json,
|
||||||
"updateDelayInProgress");
|
"updateDelayBestpathResumed",
|
||||||
} else {
|
bgp->update_delay_end_time);
|
||||||
if (bgp->update_delay_over) {
|
json_object_string_add(
|
||||||
json_object_string_add(
|
json,
|
||||||
json,
|
"updateDelayZebraUpdateResume",
|
||||||
"updateDelayFirstNeighbor",
|
bgp->update_delay_zebra_resume_time);
|
||||||
bgp->update_delay_begin_time);
|
json_object_string_add(
|
||||||
json_object_string_add(
|
json,
|
||||||
json,
|
"updateDelayPeerUpdateResume",
|
||||||
"updateDelayBestpathResumed",
|
bgp->update_delay_peers_resume_time);
|
||||||
bgp->update_delay_end_time);
|
|
||||||
json_object_string_add(
|
|
||||||
json,
|
|
||||||
"updateDelayZebraUpdateResume",
|
|
||||||
bgp->update_delay_zebra_resume_time);
|
|
||||||
json_object_string_add(
|
|
||||||
json,
|
|
||||||
"updateDelayPeerUpdateResume",
|
|
||||||
bgp->update_delay_peers_resume_time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
} else {
|
||||||
|
vty_out(vty,
|
||||||
|
"Read-only mode update-delay limit: %d seconds\n",
|
||||||
|
bgp->v_update_delay);
|
||||||
|
if (bgp->v_update_delay
|
||||||
|
!= bgp->v_establish_wait)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"Read-only mode update-delay limit: %d seconds\n",
|
" Establish wait: %d seconds\n",
|
||||||
bgp->v_update_delay);
|
bgp->v_establish_wait);
|
||||||
if (bgp->v_update_delay
|
|
||||||
!= bgp->v_establish_wait)
|
|
||||||
vty_out(vty,
|
|
||||||
" Establish wait: %d seconds\n",
|
|
||||||
bgp->v_establish_wait);
|
|
||||||
|
|
||||||
if (bgp_update_delay_active(
|
if (bgp_update_delay_active(
|
||||||
bgp)) {
|
bgp)) {
|
||||||
|
vty_out(vty,
|
||||||
|
" First neighbor established: %s\n",
|
||||||
|
bgp->update_delay_begin_time);
|
||||||
|
vty_out(vty,
|
||||||
|
" Delay in progress\n");
|
||||||
|
} else {
|
||||||
|
if (bgp->update_delay_over) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
" First neighbor established: %s\n",
|
" First neighbor established: %s\n",
|
||||||
bgp->update_delay_begin_time);
|
bgp->update_delay_begin_time);
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
" Delay in progress\n");
|
" Best-paths resumed: %s\n",
|
||||||
} else {
|
bgp->update_delay_end_time);
|
||||||
if (bgp->update_delay_over) {
|
vty_out(vty,
|
||||||
vty_out(vty,
|
" zebra update resumed: %s\n",
|
||||||
" First neighbor established: %s\n",
|
bgp->update_delay_zebra_resume_time);
|
||||||
bgp->update_delay_begin_time);
|
vty_out(vty,
|
||||||
vty_out(vty,
|
" peers update resumed: %s\n",
|
||||||
" Best-paths resumed: %s\n",
|
bgp->update_delay_peers_resume_time);
|
||||||
bgp->update_delay_end_time);
|
|
||||||
vty_out(vty,
|
|
||||||
" zebra update resumed: %s\n",
|
|
||||||
bgp->update_delay_zebra_resume_time);
|
|
||||||
vty_out(vty,
|
|
||||||
" peers update resumed: %s\n",
|
|
||||||
bgp->update_delay_peers_resume_time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_json) {
|
|
||||||
if (bgp_maxmed_onstartup_configured(bgp)
|
|
||||||
&& bgp->maxmed_active)
|
|
||||||
json_object_boolean_true_add(
|
|
||||||
json,
|
|
||||||
"maxMedOnStartup");
|
|
||||||
if (bgp->v_maxmed_admin)
|
|
||||||
json_object_boolean_true_add(
|
|
||||||
json,
|
|
||||||
"maxMedAdministrative");
|
|
||||||
|
|
||||||
json_object_int_add(
|
|
||||||
json, "tableVersion",
|
|
||||||
bgp_table_version(
|
|
||||||
bgp->rib[afi][safi]));
|
|
||||||
|
|
||||||
ents = bgp_table_count(
|
|
||||||
bgp->rib[afi][safi]);
|
|
||||||
json_object_int_add(json, "ribCount",
|
|
||||||
ents);
|
|
||||||
json_object_int_add(
|
|
||||||
json, "ribMemory",
|
|
||||||
ents * sizeof(struct bgp_node));
|
|
||||||
|
|
||||||
ents = listcount(bgp->peer);
|
|
||||||
json_object_int_add(json, "peerCount",
|
|
||||||
ents);
|
|
||||||
json_object_int_add(
|
|
||||||
json, "peerMemory",
|
|
||||||
ents * sizeof(struct peer));
|
|
||||||
|
|
||||||
if ((ents = listcount(bgp->group))) {
|
|
||||||
json_object_int_add(
|
|
||||||
json, "peerGroupCount",
|
|
||||||
ents);
|
|
||||||
json_object_int_add(
|
|
||||||
json, "peerGroupMemory",
|
|
||||||
ents * sizeof(struct
|
|
||||||
peer_group));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->af_flags[afi][safi],
|
|
||||||
BGP_CONFIG_DAMPENING))
|
|
||||||
json_object_boolean_true_add(
|
|
||||||
json,
|
|
||||||
"dampeningEnabled");
|
|
||||||
} else {
|
|
||||||
if (bgp_maxmed_onstartup_configured(bgp)
|
|
||||||
&& bgp->maxmed_active)
|
|
||||||
vty_out(vty,
|
|
||||||
"Max-med on-startup active\n");
|
|
||||||
if (bgp->v_maxmed_admin)
|
|
||||||
vty_out(vty,
|
|
||||||
"Max-med administrative active\n");
|
|
||||||
|
|
||||||
vty_out(vty,
|
|
||||||
"BGP table version %" PRIu64
|
|
||||||
"\n",
|
|
||||||
bgp_table_version(
|
|
||||||
bgp->rib[afi][safi]));
|
|
||||||
|
|
||||||
ents = bgp_table_count(
|
|
||||||
bgp->rib[afi][safi]);
|
|
||||||
vty_out(vty,
|
|
||||||
"RIB entries %ld, using %s of memory\n",
|
|
||||||
ents,
|
|
||||||
mtype_memstr(
|
|
||||||
memstrbuf,
|
|
||||||
sizeof(memstrbuf),
|
|
||||||
ents * sizeof(struct
|
|
||||||
bgp_node)));
|
|
||||||
|
|
||||||
/* Peer related usage */
|
|
||||||
ents = listcount(bgp->peer);
|
|
||||||
vty_out(vty,
|
|
||||||
"Peers %ld, using %s of memory\n",
|
|
||||||
ents,
|
|
||||||
mtype_memstr(
|
|
||||||
memstrbuf,
|
|
||||||
sizeof(memstrbuf),
|
|
||||||
ents * sizeof(struct
|
|
||||||
peer)));
|
|
||||||
|
|
||||||
if ((ents = listcount(bgp->group)))
|
|
||||||
vty_out(vty,
|
|
||||||
"Peer groups %ld, using %s of memory\n",
|
|
||||||
ents,
|
|
||||||
mtype_memstr(
|
|
||||||
memstrbuf,
|
|
||||||
sizeof(memstrbuf),
|
|
||||||
ents * sizeof(struct
|
|
||||||
peer_group)));
|
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->af_flags[afi][safi],
|
|
||||||
BGP_CONFIG_DAMPENING))
|
|
||||||
vty_out(vty,
|
|
||||||
"Dampening enabled.\n");
|
|
||||||
vty_out(vty, "\n");
|
|
||||||
|
|
||||||
/* Subtract 8 here because 'Neighbor' is
|
|
||||||
* 8 characters */
|
|
||||||
vty_out(vty, "Neighbor");
|
|
||||||
vty_out(vty, "%*s",
|
|
||||||
max_neighbor_width - 8, " ");
|
|
||||||
vty_out(vty,
|
|
||||||
"V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
json_peer = json_object_new_object();
|
if (bgp_maxmed_onstartup_configured(bgp)
|
||||||
|
&& bgp->maxmed_active)
|
||||||
if (peer_dynamic_neighbor(peer))
|
|
||||||
json_object_boolean_true_add(
|
json_object_boolean_true_add(
|
||||||
json_peer, "dynamicPeer");
|
json,
|
||||||
|
"maxMedOnStartup");
|
||||||
|
if (bgp->v_maxmed_admin)
|
||||||
|
json_object_boolean_true_add(
|
||||||
|
json,
|
||||||
|
"maxMedAdministrative");
|
||||||
|
|
||||||
if (peer->hostname)
|
|
||||||
json_object_string_add(json_peer,
|
|
||||||
"hostname",
|
|
||||||
peer->hostname);
|
|
||||||
|
|
||||||
if (peer->domainname)
|
|
||||||
json_object_string_add(
|
|
||||||
json_peer, "domainname",
|
|
||||||
peer->domainname);
|
|
||||||
|
|
||||||
json_object_int_add(json_peer, "remoteAs",
|
|
||||||
peer->as);
|
|
||||||
json_object_int_add(json_peer, "version", 4);
|
|
||||||
json_object_int_add(
|
json_object_int_add(
|
||||||
json_peer, "msgRcvd",
|
json, "tableVersion",
|
||||||
peer->open_in + peer->update_in
|
bgp_table_version(
|
||||||
+ peer->keepalive_in
|
bgp->rib[afi][safi]));
|
||||||
+ peer->notify_in
|
|
||||||
+ peer->refresh_in
|
ents = bgp_table_count(
|
||||||
+ peer->dynamic_cap_in);
|
bgp->rib[afi][safi]);
|
||||||
|
json_object_int_add(json, "ribCount",
|
||||||
|
ents);
|
||||||
json_object_int_add(
|
json_object_int_add(
|
||||||
json_peer, "msgSent",
|
json, "ribMemory",
|
||||||
peer->open_out + peer->update_out
|
ents * sizeof(struct bgp_node));
|
||||||
+ peer->keepalive_out
|
|
||||||
+ peer->notify_out
|
|
||||||
+ peer->refresh_out
|
|
||||||
+ peer->dynamic_cap_out);
|
|
||||||
|
|
||||||
json_object_int_add(json_peer, "tableVersion",
|
ents = listcount(bgp->peer);
|
||||||
peer->version[afi][safi]);
|
json_object_int_add(json, "peerCount",
|
||||||
json_object_int_add(json_peer, "outq",
|
ents);
|
||||||
peer->obuf->count);
|
|
||||||
json_object_int_add(json_peer, "inq", 0);
|
|
||||||
peer_uptime(peer->uptime, timebuf,
|
|
||||||
BGP_UPTIME_LEN, use_json,
|
|
||||||
json_peer);
|
|
||||||
json_object_int_add(
|
json_object_int_add(
|
||||||
json_peer, "prefixReceivedCount",
|
json, "peerMemory",
|
||||||
peer->pcount[afi][pfx_rcd_safi]);
|
ents * sizeof(struct peer));
|
||||||
|
|
||||||
if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
|
if ((ents = listcount(bgp->group))) {
|
||||||
json_object_string_add(json_peer,
|
json_object_int_add(
|
||||||
"state",
|
json, "peerGroupCount",
|
||||||
"Idle (Admin)");
|
ents);
|
||||||
else if (CHECK_FLAG(
|
json_object_int_add(
|
||||||
peer->sflags,
|
json, "peerGroupMemory",
|
||||||
PEER_STATUS_PREFIX_OVERFLOW))
|
ents * sizeof(struct
|
||||||
json_object_string_add(json_peer,
|
peer_group));
|
||||||
"state",
|
}
|
||||||
"Idle (PfxCt)");
|
|
||||||
else
|
|
||||||
json_object_string_add(
|
|
||||||
json_peer, "state",
|
|
||||||
lookup_msg(bgp_status_msg,
|
|
||||||
peer->status, NULL));
|
|
||||||
|
|
||||||
if (peer->conf_if)
|
if (CHECK_FLAG(bgp->af_flags[afi][safi],
|
||||||
json_object_string_add(json_peer,
|
BGP_CONFIG_DAMPENING))
|
||||||
"idType",
|
json_object_boolean_true_add(
|
||||||
"interface");
|
json,
|
||||||
else if (peer->su.sa.sa_family == AF_INET)
|
"dampeningEnabled");
|
||||||
json_object_string_add(
|
|
||||||
json_peer, "idType", "ipv4");
|
|
||||||
else if (peer->su.sa.sa_family == AF_INET6)
|
|
||||||
json_object_string_add(
|
|
||||||
json_peer, "idType", "ipv6");
|
|
||||||
|
|
||||||
json_object_object_add(json_peers, peer->host,
|
|
||||||
json_peer);
|
|
||||||
} else {
|
} else {
|
||||||
memset(dn_flag, '\0', sizeof(dn_flag));
|
if (bgp_maxmed_onstartup_configured(bgp)
|
||||||
if (peer_dynamic_neighbor(peer)) {
|
&& bgp->maxmed_active)
|
||||||
dn_count++;
|
vty_out(vty,
|
||||||
dn_flag[0] = '*';
|
"Max-med on-startup active\n");
|
||||||
}
|
if (bgp->v_maxmed_admin)
|
||||||
|
vty_out(vty,
|
||||||
|
"Max-med administrative active\n");
|
||||||
|
|
||||||
if (peer->hostname
|
vty_out(vty,
|
||||||
&& bgp_flag_check(bgp,
|
"BGP table version %" PRIu64
|
||||||
BGP_FLAG_SHOW_HOSTNAME))
|
"\n",
|
||||||
len = vty_out(vty, "%s%s(%s)", dn_flag,
|
bgp_table_version(
|
||||||
peer->hostname,
|
bgp->rib[afi][safi]));
|
||||||
peer->host);
|
|
||||||
else
|
|
||||||
len = vty_out(vty, "%s%s", dn_flag,
|
|
||||||
peer->host);
|
|
||||||
|
|
||||||
/* pad the neighbor column with spaces */
|
ents = bgp_table_count(
|
||||||
if (len < max_neighbor_width)
|
bgp->rib[afi][safi]);
|
||||||
vty_out(vty, "%*s",
|
vty_out(vty,
|
||||||
max_neighbor_width - len, " ");
|
"RIB entries %ld, using %s of memory\n",
|
||||||
|
ents,
|
||||||
|
mtype_memstr(
|
||||||
|
memstrbuf,
|
||||||
|
sizeof(memstrbuf),
|
||||||
|
ents * sizeof(struct
|
||||||
|
bgp_node)));
|
||||||
|
|
||||||
vty_out(vty, "4 %10u %7d %7d %8" PRIu64
|
/* Peer related usage */
|
||||||
" %4d %4zd %8s",
|
ents = listcount(bgp->peer);
|
||||||
peer->as,
|
vty_out(vty,
|
||||||
peer->open_in + peer->update_in
|
"Peers %ld, using %s of memory\n",
|
||||||
+ peer->keepalive_in
|
ents,
|
||||||
+ peer->notify_in
|
mtype_memstr(
|
||||||
+ peer->refresh_in
|
memstrbuf,
|
||||||
+ peer->dynamic_cap_in,
|
sizeof(memstrbuf),
|
||||||
peer->open_out + peer->update_out
|
ents * sizeof(struct
|
||||||
+ peer->keepalive_out
|
peer)));
|
||||||
+ peer->notify_out
|
|
||||||
+ peer->refresh_out
|
|
||||||
+ peer->dynamic_cap_out,
|
|
||||||
peer->version[afi][safi], 0,
|
|
||||||
peer->obuf->count,
|
|
||||||
peer_uptime(peer->uptime, timebuf,
|
|
||||||
BGP_UPTIME_LEN, 0, NULL));
|
|
||||||
|
|
||||||
if (peer->status == Established)
|
if ((ents = listcount(bgp->group)))
|
||||||
vty_out(vty, " %12ld",
|
vty_out(vty,
|
||||||
peer->pcount[afi]
|
"Peer groups %ld, using %s of memory\n",
|
||||||
[pfx_rcd_safi]);
|
ents,
|
||||||
else {
|
mtype_memstr(
|
||||||
if (CHECK_FLAG(peer->flags,
|
memstrbuf,
|
||||||
PEER_FLAG_SHUTDOWN))
|
sizeof(memstrbuf),
|
||||||
vty_out(vty, " Idle (Admin)");
|
ents * sizeof(struct
|
||||||
else if (
|
peer_group)));
|
||||||
CHECK_FLAG(
|
|
||||||
peer->sflags,
|
if (CHECK_FLAG(bgp->af_flags[afi][safi],
|
||||||
PEER_STATUS_PREFIX_OVERFLOW))
|
BGP_CONFIG_DAMPENING))
|
||||||
vty_out(vty, " Idle (PfxCt)");
|
vty_out(vty,
|
||||||
else
|
"Dampening enabled.\n");
|
||||||
vty_out(vty, " %12s",
|
|
||||||
lookup_msg(
|
|
||||||
bgp_status_msg,
|
|
||||||
peer->status,
|
|
||||||
NULL));
|
|
||||||
}
|
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
|
|
||||||
|
/* Subtract 8 here because 'Neighbor' is
|
||||||
|
* 8 characters */
|
||||||
|
vty_out(vty, "Neighbor");
|
||||||
|
vty_out(vty, "%*s",
|
||||||
|
max_neighbor_width - 8, " ");
|
||||||
|
vty_out(vty,
|
||||||
|
"V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (use_json) {
|
||||||
|
json_peer = json_object_new_object();
|
||||||
|
|
||||||
|
if (peer_dynamic_neighbor(peer))
|
||||||
|
json_object_boolean_true_add(
|
||||||
|
json_peer, "dynamicPeer");
|
||||||
|
|
||||||
|
if (peer->hostname)
|
||||||
|
json_object_string_add(json_peer,
|
||||||
|
"hostname",
|
||||||
|
peer->hostname);
|
||||||
|
|
||||||
|
if (peer->domainname)
|
||||||
|
json_object_string_add(
|
||||||
|
json_peer, "domainname",
|
||||||
|
peer->domainname);
|
||||||
|
|
||||||
|
json_object_int_add(json_peer, "remoteAs",
|
||||||
|
peer->as);
|
||||||
|
json_object_int_add(json_peer, "version", 4);
|
||||||
|
json_object_int_add(
|
||||||
|
json_peer, "msgRcvd",
|
||||||
|
peer->open_in + peer->update_in
|
||||||
|
+ peer->keepalive_in
|
||||||
|
+ peer->notify_in
|
||||||
|
+ peer->refresh_in
|
||||||
|
+ peer->dynamic_cap_in);
|
||||||
|
json_object_int_add(
|
||||||
|
json_peer, "msgSent",
|
||||||
|
peer->open_out + peer->update_out
|
||||||
|
+ peer->keepalive_out
|
||||||
|
+ peer->notify_out
|
||||||
|
+ peer->refresh_out
|
||||||
|
+ peer->dynamic_cap_out);
|
||||||
|
|
||||||
|
json_object_int_add(json_peer, "tableVersion",
|
||||||
|
peer->version[afi][safi]);
|
||||||
|
json_object_int_add(json_peer, "outq",
|
||||||
|
peer->obuf->count);
|
||||||
|
json_object_int_add(json_peer, "inq", 0);
|
||||||
|
peer_uptime(peer->uptime, timebuf,
|
||||||
|
BGP_UPTIME_LEN, use_json,
|
||||||
|
json_peer);
|
||||||
|
json_object_int_add(
|
||||||
|
json_peer, "prefixReceivedCount",
|
||||||
|
peer->pcount[afi][pfx_rcd_safi]);
|
||||||
|
|
||||||
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
|
||||||
|
json_object_string_add(json_peer,
|
||||||
|
"state",
|
||||||
|
"Idle (Admin)");
|
||||||
|
else if (CHECK_FLAG(
|
||||||
|
peer->sflags,
|
||||||
|
PEER_STATUS_PREFIX_OVERFLOW))
|
||||||
|
json_object_string_add(json_peer,
|
||||||
|
"state",
|
||||||
|
"Idle (PfxCt)");
|
||||||
|
else
|
||||||
|
json_object_string_add(
|
||||||
|
json_peer, "state",
|
||||||
|
lookup_msg(bgp_status_msg,
|
||||||
|
peer->status, NULL));
|
||||||
|
|
||||||
|
if (peer->conf_if)
|
||||||
|
json_object_string_add(json_peer,
|
||||||
|
"idType",
|
||||||
|
"interface");
|
||||||
|
else if (peer->su.sa.sa_family == AF_INET)
|
||||||
|
json_object_string_add(
|
||||||
|
json_peer, "idType", "ipv4");
|
||||||
|
else if (peer->su.sa.sa_family == AF_INET6)
|
||||||
|
json_object_string_add(
|
||||||
|
json_peer, "idType", "ipv6");
|
||||||
|
|
||||||
|
json_object_object_add(json_peers, peer->host,
|
||||||
|
json_peer);
|
||||||
|
} else {
|
||||||
|
memset(dn_flag, '\0', sizeof(dn_flag));
|
||||||
|
if (peer_dynamic_neighbor(peer)) {
|
||||||
|
dn_count++;
|
||||||
|
dn_flag[0] = '*';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer->hostname
|
||||||
|
&& bgp_flag_check(bgp,
|
||||||
|
BGP_FLAG_SHOW_HOSTNAME))
|
||||||
|
len = vty_out(vty, "%s%s(%s)", dn_flag,
|
||||||
|
peer->hostname,
|
||||||
|
peer->host);
|
||||||
|
else
|
||||||
|
len = vty_out(vty, "%s%s", dn_flag,
|
||||||
|
peer->host);
|
||||||
|
|
||||||
|
/* pad the neighbor column with spaces */
|
||||||
|
if (len < max_neighbor_width)
|
||||||
|
vty_out(vty, "%*s",
|
||||||
|
max_neighbor_width - len, " ");
|
||||||
|
|
||||||
|
vty_out(vty, "4 %10u %7d %7d %8" PRIu64
|
||||||
|
" %4d %4zd %8s",
|
||||||
|
peer->as,
|
||||||
|
peer->open_in + peer->update_in
|
||||||
|
+ peer->keepalive_in
|
||||||
|
+ peer->notify_in
|
||||||
|
+ peer->refresh_in
|
||||||
|
+ peer->dynamic_cap_in,
|
||||||
|
peer->open_out + peer->update_out
|
||||||
|
+ peer->keepalive_out
|
||||||
|
+ peer->notify_out
|
||||||
|
+ peer->refresh_out
|
||||||
|
+ peer->dynamic_cap_out,
|
||||||
|
peer->version[afi][safi], 0,
|
||||||
|
peer->obuf->count,
|
||||||
|
peer_uptime(peer->uptime, timebuf,
|
||||||
|
BGP_UPTIME_LEN, 0, NULL));
|
||||||
|
|
||||||
|
if (peer->status == Established)
|
||||||
|
vty_out(vty, " %12ld",
|
||||||
|
peer->pcount[afi]
|
||||||
|
[pfx_rcd_safi]);
|
||||||
|
else {
|
||||||
|
if (CHECK_FLAG(peer->flags,
|
||||||
|
PEER_FLAG_SHUTDOWN))
|
||||||
|
vty_out(vty, " Idle (Admin)");
|
||||||
|
else if (
|
||||||
|
CHECK_FLAG(
|
||||||
|
peer->sflags,
|
||||||
|
PEER_STATUS_PREFIX_OVERFLOW))
|
||||||
|
vty_out(vty, " Idle (PfxCt)");
|
||||||
|
else
|
||||||
|
vty_out(vty, " %12s",
|
||||||
|
lookup_msg(
|
||||||
|
bgp_status_msg,
|
||||||
|
peer->status,
|
||||||
|
NULL));
|
||||||
|
}
|
||||||
|
vty_out(vty, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
@ -11156,14 +11145,14 @@ DEFUN (no_bgp_redistribute_ipv6,
|
|||||||
return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
|
return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi,
|
void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi,
|
||||||
safi_t safi, int *write)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Unicast redistribution only. */
|
/* Unicast redistribution only. */
|
||||||
if (safi != SAFI_UNICAST)
|
if (safi != SAFI_UNICAST)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
/* Redistribute BGP does not make sense. */
|
/* Redistribute BGP does not make sense. */
|
||||||
@ -11177,11 +11166,6 @@ int bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
|
||||||
/* Display "address-family" when it is not yet
|
|
||||||
* diplayed. */
|
|
||||||
bgp_config_write_family_header(vty, afi, safi,
|
|
||||||
write);
|
|
||||||
|
|
||||||
/* "redistribute" configuration. */
|
/* "redistribute" configuration. */
|
||||||
vty_out(vty, " redistribute %s",
|
vty_out(vty, " redistribute %s",
|
||||||
zebra_route_string(i));
|
zebra_route_string(i));
|
||||||
@ -11197,7 +11181,6 @@ int bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BGP node structure. */
|
/* BGP node structure. */
|
||||||
|
@ -46,10 +46,10 @@ struct bgp;
|
|||||||
extern void bgp_vty_init(void);
|
extern void bgp_vty_init(void);
|
||||||
extern const char *afi_safi_print(afi_t, safi_t);
|
extern const char *afi_safi_print(afi_t, safi_t);
|
||||||
extern const char *afi_safi_json(afi_t, safi_t);
|
extern const char *afi_safi_json(afi_t, safi_t);
|
||||||
extern int bgp_config_write_update_delay(struct vty *, struct bgp *);
|
extern void bgp_config_write_update_delay(struct vty *, struct bgp *);
|
||||||
extern int bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp);
|
extern void bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp);
|
||||||
extern int bgp_config_write_listen(struct vty *vty, struct bgp *bgp);
|
extern void bgp_config_write_listen(struct vty *vty, struct bgp *bgp);
|
||||||
extern int bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp);
|
extern void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp);
|
||||||
extern int bgp_vty_return(struct vty *vty, int ret);
|
extern int bgp_vty_return(struct vty *vty, int ret);
|
||||||
extern struct peer *peer_and_group_lookup_vty(struct vty *vty,
|
extern struct peer *peer_and_group_lookup_vty(struct vty *vty,
|
||||||
const char *peer_str);
|
const char *peer_str);
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
extern void bgp_zebra_init(struct thread_master *master);
|
extern void bgp_zebra_init(struct thread_master *master);
|
||||||
extern void bgp_zebra_destroy(void);
|
extern void bgp_zebra_destroy(void);
|
||||||
extern int bgp_if_update_all(void);
|
extern int bgp_if_update_all(void);
|
||||||
extern int bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t, safi_t,
|
extern void bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t,
|
||||||
int *);
|
safi_t);
|
||||||
extern int bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
|
||||||
safi_t, int *);
|
safi_t);
|
||||||
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
|
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
|
||||||
struct bgp_info *, struct bgp *, afi_t, safi_t);
|
struct bgp_info *, struct bgp *, afi_t, safi_t);
|
||||||
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
|
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
|
||||||
|
346
bgpd/bgpd.c
346
bgpd/bgpd.c
@ -6204,14 +6204,8 @@ char *peer_uptime(time_t uptime2, char *buf, size_t len, u_char use_json,
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define afi_header_vty_out(vty, afi, safi, write, format, ...) \
|
|
||||||
do { \
|
|
||||||
bgp_config_write_family_header(vty, afi, safi, write); \
|
|
||||||
vty_out(vty, format, ## __VA_ARGS__); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
||||||
afi_t afi, safi_t safi, int *write)
|
afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
struct bgp_filter *gfilter = NULL;
|
struct bgp_filter *gfilter = NULL;
|
||||||
@ -6230,16 +6224,13 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
|||||||
if (!gfilter || !gfilter->dlist[in].name
|
if (!gfilter || !gfilter->dlist[in].name
|
||||||
|| strcmp(filter->dlist[in].name, gfilter->dlist[in].name)
|
|| strcmp(filter->dlist[in].name, gfilter->dlist[in].name)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s distribute-list %s in\n",
|
||||||
vty, afi, safi, write,
|
addr, filter->dlist[in].name);
|
||||||
" neighbor %s distribute-list %s in\n", addr,
|
|
||||||
filter->dlist[in].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->dlist[out].name && !gfilter) {
|
if (filter->dlist[out].name && !gfilter) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s distribute-list %s out\n", addr,
|
||||||
" neighbor %s distribute-list %s out\n",
|
filter->dlist[out].name);
|
||||||
addr, filter->dlist[out].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prefix-list. */
|
/* prefix-list. */
|
||||||
@ -6247,19 +6238,17 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
|||||||
if (!gfilter || !gfilter->plist[in].name
|
if (!gfilter || !gfilter->plist[in].name
|
||||||
|| strcmp(filter->plist[in].name, gfilter->plist[in].name)
|
|| strcmp(filter->plist[in].name, gfilter->plist[in].name)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s prefix-list %s in\n", addr,
|
||||||
" neighbor %s prefix-list %s in\n",
|
filter->plist[in].name);
|
||||||
addr, filter->plist[in].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->plist[out].name)
|
if (filter->plist[out].name)
|
||||||
if (!gfilter || !gfilter->plist[out].name
|
if (!gfilter || !gfilter->plist[out].name
|
||||||
|| strcmp(filter->plist[out].name, gfilter->plist[out].name)
|
|| strcmp(filter->plist[out].name, gfilter->plist[out].name)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s prefix-list %s out\n", addr,
|
||||||
" neighbor %s prefix-list %s out\n",
|
filter->plist[out].name);
|
||||||
addr, filter->plist[out].name);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* route-map. */
|
/* route-map. */
|
||||||
if (filter->map[RMAP_IN].name)
|
if (filter->map[RMAP_IN].name)
|
||||||
@ -6267,9 +6256,8 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
|||||||
|| strcmp(filter->map[RMAP_IN].name,
|
|| strcmp(filter->map[RMAP_IN].name,
|
||||||
gfilter->map[RMAP_IN].name)
|
gfilter->map[RMAP_IN].name)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s route-map %s in\n", addr,
|
||||||
" neighbor %s route-map %s in\n",
|
filter->map[RMAP_IN].name);
|
||||||
addr, filter->map[RMAP_IN].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->map[RMAP_OUT].name)
|
if (filter->map[RMAP_OUT].name)
|
||||||
@ -6277,16 +6265,14 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
|||||||
|| strcmp(filter->map[RMAP_OUT].name,
|
|| strcmp(filter->map[RMAP_OUT].name,
|
||||||
gfilter->map[RMAP_OUT].name)
|
gfilter->map[RMAP_OUT].name)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s route-map %s out\n", addr,
|
||||||
" neighbor %s route-map %s out\n",
|
filter->map[RMAP_OUT].name);
|
||||||
addr, filter->map[RMAP_OUT].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unsuppress-map */
|
/* unsuppress-map */
|
||||||
if (filter->usmap.name && !gfilter) {
|
if (filter->usmap.name && !gfilter) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s unsuppress-map %s\n", addr,
|
||||||
" neighbor %s unsuppress-map %s\n", addr,
|
filter->usmap.name);
|
||||||
filter->usmap.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* filter-list. */
|
/* filter-list. */
|
||||||
@ -6294,15 +6280,13 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
|
|||||||
if (!gfilter || !gfilter->aslist[in].name
|
if (!gfilter || !gfilter->aslist[in].name
|
||||||
|| strcmp(filter->aslist[in].name, gfilter->aslist[in].name)
|
|| strcmp(filter->aslist[in].name, gfilter->aslist[in].name)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s filter-list %s in\n", addr,
|
||||||
" neighbor %s filter-list %s in\n",
|
filter->aslist[in].name);
|
||||||
addr, filter->aslist[in].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->aslist[out].name && !gfilter) {
|
if (filter->aslist[out].name && !gfilter) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s filter-list %s out\n", addr,
|
||||||
" neighbor %s filter-list %s out\n", addr,
|
filter->aslist[out].name);
|
||||||
filter->aslist[out].name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6622,8 +6606,7 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
|
|||||||
|
|
||||||
/* BGP peer configuration display function. */
|
/* BGP peer configuration display function. */
|
||||||
static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
||||||
struct peer *peer, afi_t afi, safi_t safi,
|
struct peer *peer, afi_t afi, safi_t safi)
|
||||||
int *write)
|
|
||||||
{
|
{
|
||||||
struct peer *g_peer = NULL;
|
struct peer *g_peer = NULL;
|
||||||
char *addr;
|
char *addr;
|
||||||
@ -6646,36 +6629,29 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
/* If the peer-group is active but peer is not, print a 'no
|
/* If the peer-group is active but peer is not, print a 'no
|
||||||
* activate' */
|
* activate' */
|
||||||
if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) {
|
if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " no neighbor %s activate\n", addr);
|
||||||
" no neighbor %s activate\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the peer-group is not active but peer is, print an
|
/* If the peer-group is not active but peer is, print an
|
||||||
'activate' */
|
'activate' */
|
||||||
else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) {
|
else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s activate\n", addr);
|
||||||
" neighbor %s activate\n", addr);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (peer->afc[afi][safi]) {
|
if (peer->afc[afi][safi]) {
|
||||||
if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
|
if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
|
||||||
if (bgp_flag_check(bgp,
|
if (bgp_flag_check(bgp,
|
||||||
BGP_FLAG_NO_DEFAULT_IPV4)) {
|
BGP_FLAG_NO_DEFAULT_IPV4)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s activate\n",
|
||||||
vty, afi, safi, write,
|
|
||||||
" neighbor %s activate\n",
|
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s activate\n", addr);
|
||||||
" neighbor %s activate\n",
|
|
||||||
addr);
|
|
||||||
} else {
|
} else {
|
||||||
if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
|
if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
|
||||||
if (!bgp_flag_check(bgp,
|
if (!bgp_flag_check(bgp,
|
||||||
BGP_FLAG_NO_DEFAULT_IPV4)) {
|
BGP_FLAG_NO_DEFAULT_IPV4)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty,
|
||||||
vty, afi, safi, write,
|
|
||||||
" no neighbor %s activate\n",
|
" no neighbor %s activate\n",
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
@ -6686,25 +6662,20 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
/* addpath TX knobs */
|
/* addpath TX knobs */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_ADDPATH_TX_ALL_PATHS)) {
|
PEER_FLAG_ADDPATH_TX_ALL_PATHS)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s addpath-tx-all-paths\n", addr);
|
||||||
" neighbor %s addpath-tx-all-paths\n",
|
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
|
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s addpath-tx-bestpath-per-AS\n",
|
||||||
" neighbor %s addpath-tx-bestpath-per-AS\n",
|
addr);
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ORF capability. */
|
/* ORF capability. */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM)
|
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM)
|
||||||
|| peergroup_af_flag_check(peer, afi, safi,
|
|| peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_ORF_PREFIX_RM)) {
|
PEER_FLAG_ORF_PREFIX_RM)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s capability orf prefix-list", addr);
|
||||||
" neighbor %s capability orf prefix-list",
|
|
||||||
addr);
|
|
||||||
|
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_ORF_PREFIX_SM)
|
PEER_FLAG_ORF_PREFIX_SM)
|
||||||
@ -6722,57 +6693,46 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
/* Route reflector client. */
|
/* Route reflector client. */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_REFLECTOR_CLIENT)) {
|
PEER_FLAG_REFLECTOR_CLIENT)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s route-reflector-client\n", addr);
|
||||||
" neighbor %s route-reflector-client\n",
|
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next-hop-self force */
|
/* next-hop-self force */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_FORCE_NEXTHOP_SELF)) {
|
PEER_FLAG_FORCE_NEXTHOP_SELF)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s next-hop-self force\n", addr);
|
||||||
" neighbor %s next-hop-self force\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next-hop-self */
|
/* next-hop-self */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) {
|
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s next-hop-self\n", addr);
|
||||||
" neighbor %s next-hop-self\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove-private-AS */
|
/* remove-private-AS */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) {
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s remove-private-AS all replace-AS\n",
|
||||||
vty, afi, safi, write,
|
|
||||||
" neighbor %s remove-private-AS all replace-AS\n",
|
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (peergroup_af_flag_check(peer, afi, safi,
|
else if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) {
|
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s remove-private-AS replace-AS\n",
|
||||||
vty, afi, safi, write,
|
addr);
|
||||||
" neighbor %s remove-private-AS replace-AS\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (peergroup_af_flag_check(peer, afi, safi,
|
else if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s remove-private-AS all\n", addr);
|
||||||
" neighbor %s remove-private-AS all\n",
|
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (peergroup_af_flag_check(peer, afi, safi,
|
else if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS)) {
|
PEER_FLAG_REMOVE_PRIVATE_AS)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s remove-private-AS\n", addr);
|
||||||
" neighbor %s remove-private-AS\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* as-override */
|
/* as-override */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
|
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s as-override\n", addr);
|
||||||
" neighbor %s as-override\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send-community print. */
|
/* send-community print. */
|
||||||
@ -6784,27 +6744,21 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
&& peergroup_af_flag_check(
|
&& peergroup_af_flag_check(
|
||||||
peer, afi, safi,
|
peer, afi, safi,
|
||||||
PEER_FLAG_SEND_LARGE_COMMUNITY)) {
|
PEER_FLAG_SEND_LARGE_COMMUNITY)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s send-community all\n",
|
||||||
" neighbor %s send-community all\n",
|
addr);
|
||||||
addr);
|
|
||||||
} else if (peergroup_af_flag_check(
|
} else if (peergroup_af_flag_check(
|
||||||
peer, afi, safi,
|
peer, afi, safi,
|
||||||
PEER_FLAG_SEND_LARGE_COMMUNITY)) {
|
PEER_FLAG_SEND_LARGE_COMMUNITY)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s send-community large\n",
|
||||||
vty, afi, safi, write,
|
addr);
|
||||||
" neighbor %s send-community large\n", addr);
|
|
||||||
} else if (peergroup_af_flag_check(
|
} else if (peergroup_af_flag_check(
|
||||||
peer, afi, safi,
|
peer, afi, safi,
|
||||||
PEER_FLAG_SEND_EXT_COMMUNITY)) {
|
PEER_FLAG_SEND_EXT_COMMUNITY)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s send-community extended\n",
|
||||||
vty, afi, safi, write,
|
|
||||||
" neighbor %s send-community extended\n",
|
|
||||||
addr);
|
addr);
|
||||||
} else if (peergroup_af_flag_check(peer, afi, safi,
|
} else if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_SEND_COMMUNITY)) {
|
PEER_FLAG_SEND_COMMUNITY)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s send-community\n", addr);
|
||||||
" neighbor %s send-community\n",
|
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!peer_af_flag_check(peer, afi, safi,
|
if (!peer_af_flag_check(peer, afi, safi,
|
||||||
@ -6821,9 +6775,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
&& (!g_peer || peer_af_flag_check(
|
&& (!g_peer || peer_af_flag_check(
|
||||||
g_peer, afi, safi,
|
g_peer, afi, safi,
|
||||||
PEER_FLAG_SEND_LARGE_COMMUNITY))) {
|
PEER_FLAG_SEND_LARGE_COMMUNITY))) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " no neighbor %s send-community all\n",
|
||||||
vty, afi, safi, write,
|
addr);
|
||||||
" no neighbor %s send-community all\n", addr);
|
|
||||||
} else {
|
} else {
|
||||||
if (!peer_af_flag_check(peer, afi, safi,
|
if (!peer_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_SEND_LARGE_COMMUNITY)
|
PEER_FLAG_SEND_LARGE_COMMUNITY)
|
||||||
@ -6831,8 +6784,7 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
|| peer_af_flag_check(
|
|| peer_af_flag_check(
|
||||||
g_peer, afi, safi,
|
g_peer, afi, safi,
|
||||||
PEER_FLAG_SEND_LARGE_COMMUNITY))) {
|
PEER_FLAG_SEND_LARGE_COMMUNITY))) {
|
||||||
afi_header_vty_out(
|
vty_out(vty,
|
||||||
vty, afi, safi, write,
|
|
||||||
" no neighbor %s send-community large\n",
|
" no neighbor %s send-community large\n",
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
@ -6843,8 +6795,7 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
|| peer_af_flag_check(
|
|| peer_af_flag_check(
|
||||||
g_peer, afi, safi,
|
g_peer, afi, safi,
|
||||||
PEER_FLAG_SEND_EXT_COMMUNITY))) {
|
PEER_FLAG_SEND_EXT_COMMUNITY))) {
|
||||||
afi_header_vty_out(
|
vty_out(vty,
|
||||||
vty, afi, safi, write,
|
|
||||||
" no neighbor %s send-community extended\n",
|
" no neighbor %s send-community extended\n",
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
@ -6854,8 +6805,7 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
&& (!g_peer || peer_af_flag_check(
|
&& (!g_peer || peer_af_flag_check(
|
||||||
g_peer, afi, safi,
|
g_peer, afi, safi,
|
||||||
PEER_FLAG_SEND_COMMUNITY))) {
|
PEER_FLAG_SEND_COMMUNITY))) {
|
||||||
afi_header_vty_out(
|
vty_out(vty,
|
||||||
vty, afi, safi, write,
|
|
||||||
" no neighbor %s send-community\n",
|
" no neighbor %s send-community\n",
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
@ -6873,8 +6823,7 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
|| (peer->default_rmap[afi][safi].name
|
|| (peer->default_rmap[afi][safi].name
|
||||||
&& strcmp(peer->default_rmap[afi][safi].name,
|
&& strcmp(peer->default_rmap[afi][safi].name,
|
||||||
g_peer->default_rmap[afi][safi].name))))) {
|
g_peer->default_rmap[afi][safi].name))))) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s default-originate", addr);
|
||||||
" neighbor %s default-originate", addr);
|
|
||||||
if (peer->default_rmap[afi][safi].name)
|
if (peer->default_rmap[afi][safi].name)
|
||||||
vty_out(vty, " route-map %s",
|
vty_out(vty, " route-map %s",
|
||||||
peer->default_rmap[afi][safi].name);
|
peer->default_rmap[afi][safi].name);
|
||||||
@ -6883,9 +6832,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
|
|
||||||
/* Soft reconfiguration inbound. */
|
/* Soft reconfiguration inbound. */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) {
|
if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s soft-reconfiguration inbound\n",
|
||||||
vty, afi, safi, write,
|
addr);
|
||||||
" neighbor %s soft-reconfiguration inbound\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* maximum-prefix. */
|
/* maximum-prefix. */
|
||||||
@ -6898,9 +6846,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
PEER_FLAG_MAX_PREFIX_WARNING)
|
PEER_FLAG_MAX_PREFIX_WARNING)
|
||||||
!= CHECK_FLAG(peer->af_flags[afi][safi],
|
!= CHECK_FLAG(peer->af_flags[afi][safi],
|
||||||
PEER_FLAG_MAX_PREFIX_WARNING)) {
|
PEER_FLAG_MAX_PREFIX_WARNING)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s maximum-prefix %lu", addr,
|
||||||
" neighbor %s maximum-prefix %lu",
|
peer->pmax[afi][safi]);
|
||||||
addr, peer->pmax[afi][safi]);
|
|
||||||
if (peer->pmax_threshold[afi][safi]
|
if (peer->pmax_threshold[afi][safi]
|
||||||
!= MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
|
!= MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
|
||||||
vty_out(vty, " %u",
|
vty_out(vty, " %u",
|
||||||
@ -6917,16 +6864,13 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
/* Route server client. */
|
/* Route server client. */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_RSERVER_CLIENT)) {
|
PEER_FLAG_RSERVER_CLIENT)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s route-server-client\n", addr);
|
||||||
" neighbor %s route-server-client\n", addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nexthop-local unchanged. */
|
/* Nexthop-local unchanged. */
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) {
|
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s nexthop-local unchanged\n", addr);
|
||||||
" neighbor %s nexthop-local unchanged\n",
|
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allowas-in <1-10> */
|
/* allowas-in <1-10> */
|
||||||
@ -6937,14 +6881,11 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
|| peer->allowas_in[afi][safi]
|
|| peer->allowas_in[afi][safi]
|
||||||
!= g_peer->allowas_in[afi][safi]) {
|
!= g_peer->allowas_in[afi][safi]) {
|
||||||
if (peer->allowas_in[afi][safi] == 3) {
|
if (peer->allowas_in[afi][safi] == 3) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s allowas-in\n",
|
||||||
" neighbor %s allowas-in\n",
|
addr);
|
||||||
addr);
|
|
||||||
} else {
|
} else {
|
||||||
afi_header_vty_out(
|
vty_out(vty, " neighbor %s allowas-in %d\n",
|
||||||
vty, afi, safi, write,
|
addr, peer->allowas_in[afi][safi]);
|
||||||
" neighbor %s allowas-in %d\n", addr,
|
|
||||||
peer->allowas_in[afi][safi]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6955,9 +6896,7 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
if (!peer_group_active(peer)
|
if (!peer_group_active(peer)
|
||||||
|| !peer_af_flag_check(g_peer, afi, safi,
|
|| !peer_af_flag_check(g_peer, afi, safi,
|
||||||
PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
|
PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s allowas-in origin\n", addr);
|
||||||
" neighbor %s allowas-in origin\n",
|
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6967,15 +6906,13 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
|| !peer_af_flag_check(g_peer, afi, safi, PEER_FLAG_WEIGHT)
|
|| !peer_af_flag_check(g_peer, afi, safi, PEER_FLAG_WEIGHT)
|
||||||
|| peer->weight[afi][safi] != g_peer->weight[afi][safi]) {
|
|| peer->weight[afi][safi] != g_peer->weight[afi][safi]) {
|
||||||
if (peer->weight[afi][safi]) {
|
if (peer->weight[afi][safi]) {
|
||||||
afi_header_vty_out(vty, afi, safi, write,
|
vty_out(vty, " neighbor %s weight %lu\n", addr,
|
||||||
" neighbor %s weight %lu\n",
|
peer->weight[afi][safi]);
|
||||||
addr,
|
|
||||||
peer->weight[afi][safi]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter. */
|
/* Filter. */
|
||||||
bgp_config_write_filter(vty, peer, afi, safi, write);
|
bgp_config_write_filter(vty, peer, afi, safi);
|
||||||
|
|
||||||
/* atribute-unchanged. */
|
/* atribute-unchanged. */
|
||||||
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) ||
|
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) ||
|
||||||
@ -6990,8 +6927,7 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
peergroup_af_flag_check(peer, afi, safi,
|
peergroup_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_MED_UNCHANGED)) {
|
PEER_FLAG_MED_UNCHANGED)) {
|
||||||
|
|
||||||
afi_header_vty_out(
|
vty_out(vty,
|
||||||
vty, afi, safi, write,
|
|
||||||
" neighbor %s attribute-unchanged%s%s%s\n",
|
" neighbor %s attribute-unchanged%s%s%s\n",
|
||||||
addr,
|
addr,
|
||||||
peer_af_flag_check(
|
peer_af_flag_check(
|
||||||
@ -7012,64 +6948,52 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display "address-family" configuration header. */
|
|
||||||
void bgp_config_write_family_header(struct vty *vty, afi_t afi, safi_t safi,
|
|
||||||
int *write)
|
|
||||||
{
|
|
||||||
if (*write)
|
|
||||||
return;
|
|
||||||
|
|
||||||
vty_out(vty, " !\n address-family ");
|
|
||||||
|
|
||||||
if (afi == AFI_IP) {
|
|
||||||
if (safi == SAFI_UNICAST)
|
|
||||||
vty_out(vty, "ipv4 unicast");
|
|
||||||
else if (safi == SAFI_LABELED_UNICAST)
|
|
||||||
vty_out(vty, "ipv4 labeled-unicast");
|
|
||||||
else if (safi == SAFI_MULTICAST)
|
|
||||||
vty_out(vty, "ipv4 multicast");
|
|
||||||
else if (safi == SAFI_MPLS_VPN)
|
|
||||||
vty_out(vty, "ipv4 vpn");
|
|
||||||
else if (safi == SAFI_ENCAP)
|
|
||||||
vty_out(vty, "ipv4 encap");
|
|
||||||
} else if (afi == AFI_IP6) {
|
|
||||||
if (safi == SAFI_UNICAST)
|
|
||||||
vty_out(vty, "ipv6 unicast");
|
|
||||||
else if (safi == SAFI_LABELED_UNICAST)
|
|
||||||
vty_out(vty, "ipv6 labeled-unicast");
|
|
||||||
else if (safi == SAFI_MULTICAST)
|
|
||||||
vty_out(vty, "ipv6 multicast");
|
|
||||||
else if (safi == SAFI_MPLS_VPN)
|
|
||||||
vty_out(vty, "ipv6 vpn");
|
|
||||||
else if (safi == SAFI_ENCAP)
|
|
||||||
vty_out(vty, "ipv6 encap");
|
|
||||||
} else if (afi == AFI_L2VPN) {
|
|
||||||
if (safi == SAFI_EVPN)
|
|
||||||
vty_out(vty, "l2vpn evpn");
|
|
||||||
}
|
|
||||||
vty_out(vty, "\n");
|
|
||||||
|
|
||||||
*write = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Address family based peer configuration display. */
|
/* Address family based peer configuration display. */
|
||||||
static int bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
|
static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
|
||||||
safi_t safi)
|
safi_t safi)
|
||||||
{
|
{
|
||||||
int write = 0;
|
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
bgp_config_write_distance(vty, bgp, afi, safi, &write);
|
|
||||||
|
|
||||||
bgp_config_write_network(vty, bgp, afi, safi, &write);
|
vty_frame(vty, " !\n address-family ");
|
||||||
|
if (afi == AFI_IP) {
|
||||||
|
if (safi == SAFI_UNICAST)
|
||||||
|
vty_frame(vty, "ipv4 unicast");
|
||||||
|
else if (safi == SAFI_LABELED_UNICAST)
|
||||||
|
vty_frame(vty, "ipv4 labeled-unicast");
|
||||||
|
else if (safi == SAFI_MULTICAST)
|
||||||
|
vty_frame(vty, "ipv4 multicast");
|
||||||
|
else if (safi == SAFI_MPLS_VPN)
|
||||||
|
vty_frame(vty, "ipv4 vpn");
|
||||||
|
else if (safi == SAFI_ENCAP)
|
||||||
|
vty_frame(vty, "ipv4 encap");
|
||||||
|
} else if (afi == AFI_IP6) {
|
||||||
|
if (safi == SAFI_UNICAST)
|
||||||
|
vty_frame(vty, "ipv6 unicast");
|
||||||
|
else if (safi == SAFI_LABELED_UNICAST)
|
||||||
|
vty_frame(vty, "ipv6 labeled-unicast");
|
||||||
|
else if (safi == SAFI_MULTICAST)
|
||||||
|
vty_frame(vty, "ipv6 multicast");
|
||||||
|
else if (safi == SAFI_MPLS_VPN)
|
||||||
|
vty_frame(vty, "ipv6 vpn");
|
||||||
|
else if (safi == SAFI_ENCAP)
|
||||||
|
vty_frame(vty, "ipv6 encap");
|
||||||
|
} else if (afi == AFI_L2VPN) {
|
||||||
|
if (safi == SAFI_EVPN)
|
||||||
|
vty_frame(vty, "l2vpn evpn");
|
||||||
|
}
|
||||||
|
vty_frame(vty, "\n");
|
||||||
|
|
||||||
bgp_config_write_redistribute(vty, bgp, afi, safi, &write);
|
bgp_config_write_distance(vty, bgp, afi, safi);
|
||||||
|
|
||||||
|
bgp_config_write_network(vty, bgp, afi, safi);
|
||||||
|
|
||||||
|
bgp_config_write_redistribute(vty, bgp, afi, safi);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
|
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
|
||||||
bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi,
|
bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
|
||||||
&write);
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||||
/* Skip dynamic neighbors. */
|
/* Skip dynamic neighbors. */
|
||||||
@ -7078,20 +7002,16 @@ static int bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
|
|
||||||
/* Do not display doppelganger peers */
|
/* Do not display doppelganger peers */
|
||||||
if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
|
||||||
bgp_config_write_peer_af(vty, bgp, peer, afi, safi,
|
bgp_config_write_peer_af(vty, bgp, peer, afi, safi);
|
||||||
&write);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_config_write_maxpaths(vty, bgp, afi, safi, &write);
|
bgp_config_write_maxpaths(vty, bgp, afi, safi);
|
||||||
bgp_config_write_table_map(vty, bgp, afi, safi, &write);
|
bgp_config_write_table_map(vty, bgp, afi, safi);
|
||||||
|
|
||||||
if (safi == SAFI_EVPN)
|
if (safi == SAFI_EVPN)
|
||||||
bgp_config_write_evpn_info(vty, bgp, afi, safi, &write);
|
bgp_config_write_evpn_info(vty, bgp, afi, safi);
|
||||||
|
|
||||||
if (write)
|
vty_endframe(vty, " exit-address-family\n");
|
||||||
vty_out(vty, " exit-address-family\n");
|
|
||||||
|
|
||||||
return write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_config_write(struct vty *vty)
|
int bgp_config_write(struct vty *vty)
|
||||||
@ -7119,11 +7039,11 @@ int bgp_config_write(struct vty *vty)
|
|||||||
vty_out(vty, "bgp route-map delay-timer %u\n",
|
vty_out(vty, "bgp route-map delay-timer %u\n",
|
||||||
bm->rmap_update_timer);
|
bm->rmap_update_timer);
|
||||||
|
|
||||||
|
if (write)
|
||||||
|
vty_out(vty, "!\n");
|
||||||
|
|
||||||
/* BGP configuration. */
|
/* BGP configuration. */
|
||||||
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
||||||
if (write)
|
|
||||||
vty_out(vty, "!\n");
|
|
||||||
|
|
||||||
/* Router bgp ASN */
|
/* Router bgp ASN */
|
||||||
vty_out(vty, "router bgp %u", bgp->as);
|
vty_out(vty, "router bgp %u", bgp->as);
|
||||||
|
|
||||||
@ -7343,54 +7263,46 @@ int bgp_config_write(struct vty *vty)
|
|||||||
vty_out(vty, " no auto-summary\n");
|
vty_out(vty, " no auto-summary\n");
|
||||||
|
|
||||||
/* IPv4 unicast configuration. */
|
/* IPv4 unicast configuration. */
|
||||||
write +=
|
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
|
||||||
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
|
|
||||||
|
|
||||||
/* IPv4 multicast configuration. */
|
/* IPv4 multicast configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP,
|
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MULTICAST);
|
||||||
SAFI_MULTICAST);
|
|
||||||
|
|
||||||
/* IPv4 labeled-unicast configuration. */
|
/* IPv4 labeled-unicast configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP,
|
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_LABELED_UNICAST);
|
||||||
SAFI_LABELED_UNICAST);
|
|
||||||
|
|
||||||
/* IPv4 VPN configuration. */
|
/* IPv4 VPN configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP,
|
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MPLS_VPN);
|
||||||
SAFI_MPLS_VPN);
|
|
||||||
|
|
||||||
/* ENCAPv4 configuration. */
|
/* ENCAPv4 configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP);
|
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP);
|
||||||
|
|
||||||
/* IPv6 unicast configuration. */
|
/* IPv6 unicast configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP6,
|
bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST);
|
||||||
SAFI_UNICAST);
|
|
||||||
|
|
||||||
/* IPv6 multicast configuration. */
|
/* IPv6 multicast configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP6,
|
bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MULTICAST);
|
||||||
SAFI_MULTICAST);
|
|
||||||
|
|
||||||
/* IPv6 labeled-unicast configuration. */
|
/* IPv6 labeled-unicast configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP6,
|
bgp_config_write_family(vty, bgp, AFI_IP6,
|
||||||
SAFI_LABELED_UNICAST);
|
SAFI_LABELED_UNICAST);
|
||||||
|
|
||||||
/* IPv6 VPN configuration. */
|
/* IPv6 VPN configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP6,
|
bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
|
||||||
SAFI_MPLS_VPN);
|
|
||||||
|
|
||||||
/* ENCAPv6 configuration. */
|
/* ENCAPv6 configuration. */
|
||||||
write += bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP);
|
bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP);
|
||||||
|
|
||||||
/* EVPN configuration. */
|
/* EVPN configuration. */
|
||||||
write +=
|
bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN);
|
||||||
bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN);
|
|
||||||
|
|
||||||
#if ENABLE_BGP_VNC
|
#if ENABLE_BGP_VNC
|
||||||
write += bgp_rfapi_cfg_write(vty, bgp);
|
bgp_rfapi_cfg_write(vty, bgp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
write++;
|
vty_out(vty, "!\n");
|
||||||
}
|
}
|
||||||
return write;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_master_init(struct thread_master *master)
|
void bgp_master_init(struct thread_master *master)
|
||||||
|
@ -1238,7 +1238,6 @@ extern void peer_xfer_config(struct peer *dst, struct peer *src);
|
|||||||
extern char *peer_uptime(time_t, char *, size_t, u_char, json_object *);
|
extern char *peer_uptime(time_t, char *, size_t, u_char, json_object *);
|
||||||
|
|
||||||
extern int bgp_config_write(struct vty *);
|
extern int bgp_config_write(struct vty *);
|
||||||
extern void bgp_config_write_family_header(struct vty *, afi_t, safi_t, int *);
|
|
||||||
|
|
||||||
extern void bgp_master_init(struct thread_master *master);
|
extern void bgp_master_init(struct thread_master *master);
|
||||||
|
|
||||||
|
@ -1837,6 +1837,7 @@ AC_CONFIG_FILES([Makefile
|
|||||||
doc/watchfrr.8
|
doc/watchfrr.8
|
||||||
doc/zebra.8
|
doc/zebra.8
|
||||||
doc/frr.1
|
doc/frr.1
|
||||||
|
doc/frr-args.8
|
||||||
pkgsrc/bgpd.sh pkgsrc/ospf6d.sh pkgsrc/ospfd.sh
|
pkgsrc/bgpd.sh pkgsrc/ospf6d.sh pkgsrc/ospfd.sh
|
||||||
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
|
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
|
||||||
pkgsrc/eigrpd.sh])
|
pkgsrc/eigrpd.sh])
|
||||||
|
1
debian/frr.install
vendored
1
debian/frr.install
vendored
@ -16,6 +16,7 @@ usr/share/man/man8/ripngd.8
|
|||||||
usr/share/man/man8/zebra.8
|
usr/share/man/man8/zebra.8
|
||||||
usr/share/man/man8/isisd.8
|
usr/share/man/man8/isisd.8
|
||||||
usr/share/man/man8/watchfrr.8
|
usr/share/man/man8/watchfrr.8
|
||||||
|
usr/share/man/man8/frr-args.8
|
||||||
usr/share/snmp/mibs/
|
usr/share/snmp/mibs/
|
||||||
tools/etc/* etc/
|
tools/etc/* etc/
|
||||||
tools/*.service lib/systemd/system
|
tools/*.service lib/systemd/system
|
||||||
|
@ -79,7 +79,7 @@ frr_TEXINFOS = appendix.texi basic.texi bgpd.texi isisd.texi filter.texi \
|
|||||||
.dia.png:
|
.dia.png:
|
||||||
$(DIATOPNG) "$@" $<
|
$(DIATOPNG) "$@" $<
|
||||||
|
|
||||||
man_MANS = frr.1
|
man_MANS = frr.1 frr-args.8
|
||||||
|
|
||||||
if PIMD
|
if PIMD
|
||||||
man_MANS += pimd.8
|
man_MANS += pimd.8
|
||||||
|
248
doc/frr-args.8.in
Normal file
248
doc/frr-args.8.in
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
.TH frr-args 8 "28 August 2017" "@PACKAGE_FULLNAME@ general options" "Version @PACKAGE_VERSION@"
|
||||||
|
.SH NAME
|
||||||
|
frr-args \- common command line options for all @PACKAGE_FULLNAME@ daemons.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
<\fBzebra\fR|\fBbgpd\fR|\fB...\fR>
|
||||||
|
[\fB\-h\fR] [\fB\-v\fR]
|
||||||
|
|
||||||
|
<\fBzebra\fR|\fBbgpd\fR|\fB...\fR>
|
||||||
|
[\fB\-d\fR|\fB\-t\fR|\fB\-dt\fR]
|
||||||
|
[\fB\-C\fR]
|
||||||
|
[\fB\-f\fR \fIconfig-file\fR]
|
||||||
|
[\fB\-i\fR \fIpid-file\fR]
|
||||||
|
[\fB\-z\fR \fIzclient-path\fR]
|
||||||
|
[\fB\-u\fR \fIuser\fR]
|
||||||
|
[\fB\-g\fR \fIgroup\fR]
|
||||||
|
[\fB\-A\fR \fIvty-addr\fR]
|
||||||
|
[\fB\-P\fR \fIvty-port\fR]
|
||||||
|
[\fB\-M\fR \fImodule\fR[\fB:\fIoptions\fR]]
|
||||||
|
[\fB\-N\fR \fIpathspace\fR]
|
||||||
|
[\fB\-\-vty_socket\fR \fIvty-path\fR]
|
||||||
|
[\fB\-\-moduledir\fR \fImodule-path\fR]
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
@PACKAGE_NAME@ daemons share a large part of their command line options;
|
||||||
|
this man page documents these. For options on specific daemons please refer
|
||||||
|
to their respective man pages. Most of the common options are related to
|
||||||
|
process control, configuration and common library functionality.
|
||||||
|
|
||||||
|
.SH HELP AND VERSION
|
||||||
|
.TP
|
||||||
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
Print a short description of the daemon's command line options.
|
||||||
|
.TP
|
||||||
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
|
Print version and build information for the daemon.
|
||||||
|
.PP
|
||||||
|
Both of these options inhibit normal operation and will immediately exit.
|
||||||
|
|
||||||
|
.SH PROCESS CONTROL
|
||||||
|
These options control background operation:
|
||||||
|
.TP
|
||||||
|
\fB\-d\fR, \fB\-\-daemon\fR
|
||||||
|
Launches the process in background/daemon mode, forking and detaching from
|
||||||
|
the terminal.
|
||||||
|
|
||||||
|
The parent process will delay its exit until the daemon/child has finished
|
||||||
|
its initialization and has entered its main loop. This is important for
|
||||||
|
\fBzebra\fR startup because the other daemons will attempt to connect to
|
||||||
|
\fBzebra\fR. A return from \fBzebra -d\fR guarantees its readiness to
|
||||||
|
accept these connections.
|
||||||
|
.TP
|
||||||
|
\fB\-t\fR, \fB\-\-terminal\fR
|
||||||
|
Opens an interactive VTY session on the terminal, allowing for both state
|
||||||
|
and configuration operations. Note that the terminal starts operating after
|
||||||
|
startup has completed and the configuration file has been loaded.
|
||||||
|
|
||||||
|
The process will exit when end of file is detected on the terminal. It is
|
||||||
|
possible to daemonize a process started with \fB-t\fR (but without \fB-d\fR)
|
||||||
|
by sending \fISIGQUIT\fR to the process (normally mapped to a \fI^\\\fR
|
||||||
|
keypress.)
|
||||||
|
.TP
|
||||||
|
\fB\-dt\fR, \fB\-\-daemon \-\-terminal\fR
|
||||||
|
This combination of the previous two options will delay the daemon from
|
||||||
|
going into background until the terminal session ends (by end of file.)
|
||||||
|
|
||||||
|
If the process receives \fISIGINT\fR (e.g. a \fI^C\fR keypress) in this
|
||||||
|
mode, it will exit instead of daemonizing.
|
||||||
|
.PP
|
||||||
|
It is safe to suspend (\fISIGTSTP\fR / \fI^Z\fR) the terminal session
|
||||||
|
opened by the previous two options; this will only stop the terminal but
|
||||||
|
not the protocol daemon itself (which runs in a separate second process.)
|
||||||
|
|
||||||
|
.SH CONFIGURATION AND PATHS
|
||||||
|
The following options control configuration and file system locations for
|
||||||
|
@PACKAGE_NAME@ processes:
|
||||||
|
.TP
|
||||||
|
\fB\-f\fR, \fB\-\-config_file\fR \fIconfig-file\fR
|
||||||
|
Specify a configuration file to be used instead of the default
|
||||||
|
\fB\fI@CFG_SYSCONF@/<daemon>.conf\fR file.
|
||||||
|
|
||||||
|
Note that the daemon will attempt to write to this file if the
|
||||||
|
\fIwrite file\fR command is issued on its VTY interface or through
|
||||||
|
\fBvtysh\fR.
|
||||||
|
.TP
|
||||||
|
\fB\-C\fR, \fB\-\-dryrun\fR
|
||||||
|
Load the configuration file and check its validity, then exit.
|
||||||
|
.TP
|
||||||
|
\fB\-i\fR, \fB\-\-pid_file\fR \fIpid-file\fR
|
||||||
|
Output a pid file to a location other than the default
|
||||||
|
\fB\fI@CFG_STATE@/<daemon>.pid\fR.
|
||||||
|
.TP
|
||||||
|
\fB\-z\fR, \fB\-\-socket\fR \fIzclient-path\fR
|
||||||
|
Override the path of the ZAPI socket used to communicate between \fBzebra\fR
|
||||||
|
and the various protocol daemons. The default is
|
||||||
|
\fB\fI@CFG_STATE@/zserv.api\fR. The value of this option must be the same
|
||||||
|
across all daemons.
|
||||||
|
.TP
|
||||||
|
\fB\-N\fR, \fB\-\-pathspace\fR \fIpathspace\fR
|
||||||
|
Insert \fIpathspace\fR into all default paths, changing the defaults to:
|
||||||
|
.IP
|
||||||
|
\fB@CFG_SYSCONF@/\fIpathspace\fB/<daemon>.conf\fR
|
||||||
|
.br
|
||||||
|
\fB@CFG_STATE@/\fIpathspace\fB/<daemon>.pid\fR
|
||||||
|
.br
|
||||||
|
\fB@CFG_STATE@/\fIpathspace\fB/<daemon>.vty\fR
|
||||||
|
.br
|
||||||
|
\fB@CFG_STATE@/\fIpathspace\fB/zserv.api\fR
|
||||||
|
|
||||||
|
\'.\' and \'/\' characters will not be accepted in \fIpathspace\fR, but the
|
||||||
|
empty string will be accepted.
|
||||||
|
|
||||||
|
Note that this only changes the respective defaults, it has no effect on
|
||||||
|
the respective path if the \fB\-f\fR, \fB\-i\fR, \fB\-z\fR or
|
||||||
|
\fB\-\-vty_socket\fR options are used.
|
||||||
|
|
||||||
|
The purpose of this option is to easily group all file system related
|
||||||
|
bits together for running multiple fully-separate "logical routers" on a
|
||||||
|
system, particularly with Linux network namespaces. Groups of daemons
|
||||||
|
running with distinct \fIpathspace\fR values will be completely unaware
|
||||||
|
of each other and not interact in any way.
|
||||||
|
|
||||||
|
This option does not do any system setup (like network namespaces.) This
|
||||||
|
must be done by the user, for example by running:
|
||||||
|
.IP
|
||||||
|
\fBip netns exec \fInamespace \fB<daemon> -N \fInamespace\fR
|
||||||
|
|
||||||
|
.SH PROCESS CREDENTIALS
|
||||||
|
.TP
|
||||||
|
\fB\-u\fR, \fB\-\-user\fR \fIuser\fR
|
||||||
|
(default: \fB@enable_user@\fR)
|
||||||
|
.TP
|
||||||
|
\fB\-g\fR, \fB\-\-group\fR \fIgroup\fR
|
||||||
|
(default: \fB@enable_group@\fR)
|
||||||
|
.IP
|
||||||
|
Change the user/group which the daemon will switch to.
|
||||||
|
.PP
|
||||||
|
Note that there is an additional group, \fB@enable_vty_group@\fR, which
|
||||||
|
controls group ownership of the VTY sockets. The name of this group cannot
|
||||||
|
currently be changed, and \fIuser\fR must be a member of this group.
|
||||||
|
|
||||||
|
.SH VTY SETUP
|
||||||
|
These following options control the daemon's VTY (interactive command line)
|
||||||
|
interface. The interface is available over TCP, using the telnet protocol,
|
||||||
|
as well as through the \fBvtysh\fR frontend.
|
||||||
|
.TP
|
||||||
|
\fB\-A\fR, \fB--vty_addr\fR \fIvty-addr\fR
|
||||||
|
Specify an IP/IPv6 address to bind the TCP VTY interface to. It is
|
||||||
|
generally recommended to specify \fI::1\fR or \fI127.0.0.1\fR. For reasons
|
||||||
|
of backwards compatibility, the default is to listen on all interfaces.
|
||||||
|
.TP
|
||||||
|
\fB\-P\fR, \fB--vty_port\fR \fIvty-port\fR
|
||||||
|
Override the daemon's default TCP VTY port (each daemon has a different
|
||||||
|
default value upwards of 2600, listed below.) Specifying \fI0\fR disables
|
||||||
|
the TCP VTY interface.
|
||||||
|
|
||||||
|
Default ports are:
|
||||||
|
|
||||||
|
.ta 16m
|
||||||
|
zebra 2601
|
||||||
|
.br
|
||||||
|
ripd 2602
|
||||||
|
.br
|
||||||
|
ripngd 2603
|
||||||
|
.br
|
||||||
|
ospfd 2604
|
||||||
|
.br
|
||||||
|
bgpd 2605
|
||||||
|
.br
|
||||||
|
ospf6d 2606
|
||||||
|
.br
|
||||||
|
isisd 2608
|
||||||
|
.br
|
||||||
|
babeld 2609
|
||||||
|
.br
|
||||||
|
nhrpd 2610
|
||||||
|
.br
|
||||||
|
pimd 2611
|
||||||
|
.br
|
||||||
|
ldpd 2612
|
||||||
|
.br
|
||||||
|
eigrpd 2613
|
||||||
|
|
||||||
|
Port 2607 is used for ospfd's Opaque LSA API, while port 2600 is used for
|
||||||
|
the (insecure) TCP-ZEBRA interface.
|
||||||
|
.TP
|
||||||
|
\fB\-\-vty_socket\fR \fIvty-path\fR
|
||||||
|
Overrides the directory used for the \fB<daemon>.vty\fR sockets.
|
||||||
|
\fBvtysh\fR connects to these sockets in order to access each daemon's
|
||||||
|
VTY.
|
||||||
|
.br
|
||||||
|
Default: \fB\fI@CFG_STATE@\fR[\fB/\fI<pathspace>\fR]
|
||||||
|
|
||||||
|
NB: Unlike the other options, this option specifies a \fBdirectory\fR,
|
||||||
|
not a full path.
|
||||||
|
|
||||||
|
This option is primarily used by the SNAP packaging system, its semantics
|
||||||
|
may change. It should not be neccessary in most other scenarios.
|
||||||
|
|
||||||
|
.SH MODULE LOADING
|
||||||
|
@PACKAGE_NAME@ supports optional dynamically loadable modules, although
|
||||||
|
these can only be loaded at startup. The set of available modules may vary
|
||||||
|
across distributions and packages, and modules may be available for
|
||||||
|
installation as separate packages.
|
||||||
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module\fR \fImodule\fR[\fB:\fIoptions\fR]
|
||||||
|
Load a module named \fImodule\fR, optionally passing \fIoptions\fR to it.
|
||||||
|
|
||||||
|
If there is a \'/\' character in \fImodule\fR, the value is assumed to be
|
||||||
|
a pathname to a module.
|
||||||
|
|
||||||
|
If there is no \'/\' character, the module directory (see next option)
|
||||||
|
is searched first for a module named "\fI<daemon>\fB_\fI<module>\fB.so\fR",
|
||||||
|
then for "\fI<module>\fB.so\fR".
|
||||||
|
This allows for a module to exist in variations appropriate for particular
|
||||||
|
daemons, e.g. \fIzebra_snmp\fR and \fIbgp_snmp\fR, with the correct one
|
||||||
|
selected by \fI\-M snmp\fR.
|
||||||
|
|
||||||
|
The meaning of \fIoptions\fR is specific to the module being loaded. Most
|
||||||
|
modules currently ignore it.
|
||||||
|
|
||||||
|
Modules are loaded in the order as listed on the command line. This is
|
||||||
|
not generally relevant.
|
||||||
|
.TP
|
||||||
|
\fB\-\-moduledir\fR \fImodule-path\fR
|
||||||
|
Look for modules in the \fImodule-path\fR directory instead of the default
|
||||||
|
\fI@CFG_MODULE@\fR. (This path is \fBnot\fR affected by the \fB\-N\fR
|
||||||
|
option.)
|
||||||
|
.PP
|
||||||
|
The list of loaded modules can be inspected at runtime with the
|
||||||
|
\fBshow modules\fR VTY command.
|
||||||
|
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR zebra (8),
|
||||||
|
.BR vtysh (1),
|
||||||
|
.BR ripd (8),
|
||||||
|
.BR ripngd (8),
|
||||||
|
.BR ospfd (8),
|
||||||
|
.BR ospf6d (8),
|
||||||
|
.BR bgpd (8),
|
||||||
|
.BR isisd (8),
|
||||||
|
.BR babeld (8),
|
||||||
|
.BR nhrpd (8),
|
||||||
|
.BR pimd (8),
|
||||||
|
.BR ldpd (8),
|
||||||
|
.BR eigrpd (8)
|
||||||
|
|
||||||
|
\fIhttps://frrouting.org/
|
@ -93,7 +93,7 @@ static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp)
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||||
vty_out(vty, "interface %s\n", ei->ifp->name);
|
vty_frame(vty, "interface %s\n", ei->ifp->name);
|
||||||
|
|
||||||
if ((IF_DEF_PARAMS(ei->ifp)->auth_type)
|
if ((IF_DEF_PARAMS(ei->ifp)->auth_type)
|
||||||
== EIGRP_AUTH_TYPE_MD5) {
|
== EIGRP_AUTH_TYPE_MD5) {
|
||||||
@ -128,7 +128,7 @@ static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*Separate this EIGRP interface configuration from the others*/
|
/*Separate this EIGRP interface configuration from the others*/
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -140,7 +140,7 @@ static int eigrp_write_interface(struct vty *vty)
|
|||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
|
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out(vty, " description %s\n", ifp->desc);
|
vty_out(vty, " description %s\n", ifp->desc);
|
||||||
@ -157,7 +157,7 @@ static int eigrp_write_interface(struct vty *vty)
|
|||||||
vty_out(vty, " ip hold-time eigrp %u\n",
|
vty_out(vty, " ip hold-time eigrp %u\n",
|
||||||
IF_DEF_PARAMS(ifp)->v_wait);
|
IF_DEF_PARAMS(ifp)->v_wait);
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -948,7 +948,7 @@ int isis_interface_config_write(struct vty *vty)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* IF name */
|
/* IF name */
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
write++;
|
write++;
|
||||||
/* IF desc */
|
/* IF desc */
|
||||||
if (ifp->desc) {
|
if (ifp->desc) {
|
||||||
@ -1145,7 +1145,7 @@ int isis_interface_config_write(struct vty *vty)
|
|||||||
}
|
}
|
||||||
write += circuit_write_mt_settings(circuit, vty);
|
write += circuit_write_mt_settings(circuit, vty);
|
||||||
}
|
}
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
|
50
lib/libfrr.c
50
lib/libfrr.c
@ -101,13 +101,15 @@ static const struct optspec os_always = {
|
|||||||
static const struct option lo_cfg_pid_dry[] = {
|
static const struct option lo_cfg_pid_dry[] = {
|
||||||
{"pid_file", required_argument, NULL, 'i'},
|
{"pid_file", required_argument, NULL, 'i'},
|
||||||
{"config_file", required_argument, NULL, 'f'},
|
{"config_file", required_argument, NULL, 'f'},
|
||||||
|
{"pathspace", required_argument, NULL, 'N'},
|
||||||
{"dryrun", no_argument, NULL, 'C'},
|
{"dryrun", no_argument, NULL, 'C'},
|
||||||
{"terminal", no_argument, NULL, 't'},
|
{"terminal", no_argument, NULL, 't'},
|
||||||
{NULL}};
|
{NULL}};
|
||||||
static const struct optspec os_cfg_pid_dry = {
|
static const struct optspec os_cfg_pid_dry = {
|
||||||
"f:i:Ct",
|
"f:i:CtN:",
|
||||||
" -f, --config_file Set configuration file name\n"
|
" -f, --config_file Set configuration file name\n"
|
||||||
" -i, --pid_file Set process identifier file name\n"
|
" -i, --pid_file Set process identifier file name\n"
|
||||||
|
" -N, --pathspace Insert prefix into config & socket paths\n"
|
||||||
" -C, --dryrun Check configuration for validity and exit\n"
|
" -C, --dryrun Check configuration for validity and exit\n"
|
||||||
" -t, --terminal Open terminal session on stdio\n"
|
" -t, --terminal Open terminal session on stdio\n"
|
||||||
" -d -t Daemonize after terminal session ends\n",
|
" -d -t Daemonize after terminal session ends\n",
|
||||||
@ -351,6 +353,23 @@ static int frr_opt(int opt)
|
|||||||
return 1;
|
return 1;
|
||||||
di->config_file = optarg;
|
di->config_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'N':
|
||||||
|
if (di->flags & FRR_NO_CFG_PID_DRY)
|
||||||
|
return 1;
|
||||||
|
if (di->pathspace) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"-N/--pathspace option specified more than once!\n");
|
||||||
|
errors++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strchr(optarg, '/') || strchr(optarg, '.')) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"slashes or dots are not permitted in the --pathspace option.\n");
|
||||||
|
errors++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
di->pathspace = optarg;
|
||||||
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (di->flags & FRR_NO_CFG_PID_DRY)
|
if (di->flags & FRR_NO_CFG_PID_DRY)
|
||||||
return 1;
|
return 1;
|
||||||
@ -500,14 +519,25 @@ struct thread_master *frr_init(void)
|
|||||||
struct option_chain *oc;
|
struct option_chain *oc;
|
||||||
struct frrmod_runtime *module;
|
struct frrmod_runtime *module;
|
||||||
char moderr[256];
|
char moderr[256];
|
||||||
|
char p_instance[16] = "", p_pathspace[256] = "";
|
||||||
const char *dir;
|
const char *dir;
|
||||||
dir = di->module_path ? di->module_path : frr_moduledir;
|
dir = di->module_path ? di->module_path : frr_moduledir;
|
||||||
|
|
||||||
srandom(time(NULL));
|
srandom(time(NULL));
|
||||||
|
|
||||||
if (di->instance)
|
if (di->instance) {
|
||||||
snprintf(frr_protonameinst, sizeof(frr_protonameinst), "%s[%u]",
|
snprintf(frr_protonameinst, sizeof(frr_protonameinst), "%s[%u]",
|
||||||
di->logname, di->instance);
|
di->logname, di->instance);
|
||||||
|
snprintf(p_instance, sizeof(p_instance), "-%d", di->instance);
|
||||||
|
}
|
||||||
|
if (di->pathspace)
|
||||||
|
snprintf(p_pathspace, sizeof(p_pathspace), "/%s",
|
||||||
|
di->pathspace);
|
||||||
|
|
||||||
|
snprintf(config_default, sizeof(config_default), "%s%s/%s%s.conf",
|
||||||
|
frr_sysconfdir, p_pathspace, di->name, p_instance);
|
||||||
|
snprintf(pidfile_default, sizeof(pidfile_default), "%s%s/%s%s.pid",
|
||||||
|
frr_vtydir, p_pathspace, di->name, p_instance);
|
||||||
|
|
||||||
zprivs_preinit(di->privs);
|
zprivs_preinit(di->privs);
|
||||||
|
|
||||||
@ -695,14 +725,6 @@ void frr_config_fork(void)
|
|||||||
{
|
{
|
||||||
hook_call(frr_late_init, master);
|
hook_call(frr_late_init, master);
|
||||||
|
|
||||||
if (di->instance) {
|
|
||||||
snprintf(config_default, sizeof(config_default),
|
|
||||||
"%s/%s-%d.conf", frr_sysconfdir, di->name,
|
|
||||||
di->instance);
|
|
||||||
snprintf(pidfile_default, sizeof(pidfile_default),
|
|
||||||
"%s/%s-%d.pid", frr_vtydir, di->name, di->instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
vty_read_config(di->config_file, config_default);
|
vty_read_config(di->config_file, config_default);
|
||||||
|
|
||||||
/* Don't start execution if we are in dry-run mode */
|
/* Don't start execution if we are in dry-run mode */
|
||||||
@ -723,7 +745,13 @@ void frr_vty_serv(void)
|
|||||||
* (not currently set anywhere) */
|
* (not currently set anywhere) */
|
||||||
if (!di->vty_path) {
|
if (!di->vty_path) {
|
||||||
const char *dir;
|
const char *dir;
|
||||||
dir = di->vty_sock_path ? di->vty_sock_path : frr_vtydir;
|
char defvtydir[256];
|
||||||
|
|
||||||
|
snprintf(defvtydir, sizeof(defvtydir), "%s%s%s", frr_vtydir,
|
||||||
|
di->pathspace ? "/" : "",
|
||||||
|
di->pathspace ? di->pathspace : "");
|
||||||
|
|
||||||
|
dir = di->vty_sock_path ? di->vty_sock_path : defvtydir;
|
||||||
|
|
||||||
if (di->instance)
|
if (di->instance)
|
||||||
snprintf(vtypath_default, sizeof(vtypath_default),
|
snprintf(vtypath_default, sizeof(vtypath_default),
|
||||||
|
@ -54,6 +54,7 @@ struct frr_daemon_info {
|
|||||||
const char *pid_file;
|
const char *pid_file;
|
||||||
const char *vty_path;
|
const char *vty_path;
|
||||||
const char *module_path;
|
const char *module_path;
|
||||||
|
const char *pathspace;
|
||||||
|
|
||||||
const char *proghelp;
|
const char *proghelp;
|
||||||
void (*printhelp)(FILE *target);
|
void (*printhelp)(FILE *target);
|
||||||
|
24
lib/vty.c
24
lib/vty.c
@ -91,6 +91,25 @@ char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
|
|||||||
|
|
||||||
static int do_log_commands = 0;
|
static int do_log_commands = 0;
|
||||||
|
|
||||||
|
void vty_frame(struct vty *vty, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
vsnprintf(vty->frame + vty->frame_pos,
|
||||||
|
sizeof(vty->frame) - vty->frame_pos,
|
||||||
|
format, args);
|
||||||
|
vty->frame_pos = strlen(vty->frame);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vty_endframe(struct vty *vty, const char *endtext)
|
||||||
|
{
|
||||||
|
if (vty->frame_pos == 0 && endtext)
|
||||||
|
vty_out(vty, "%s", endtext);
|
||||||
|
vty->frame_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* VTY standard output function. */
|
/* VTY standard output function. */
|
||||||
int vty_out(struct vty *vty, const char *format, ...)
|
int vty_out(struct vty *vty, const char *format, ...)
|
||||||
{
|
{
|
||||||
@ -100,6 +119,11 @@ int vty_out(struct vty *vty, const char *format, ...)
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
|
||||||
|
if (vty->frame_pos) {
|
||||||
|
vty->frame_pos = 0;
|
||||||
|
vty_out(vty, "%s", vty->frame);
|
||||||
|
}
|
||||||
|
|
||||||
if (vty_shell(vty)) {
|
if (vty_shell(vty)) {
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vprintf(format, args);
|
vprintf(format, args);
|
||||||
|
15
lib/vty.h
15
lib/vty.h
@ -125,6 +125,12 @@ struct vty {
|
|||||||
|
|
||||||
/* What address is this vty comming from. */
|
/* What address is this vty comming from. */
|
||||||
char address[SU_ADDRSTRLEN];
|
char address[SU_ADDRSTRLEN];
|
||||||
|
|
||||||
|
/* "frame" output. This is buffered and will be printed if some
|
||||||
|
* actual output follows, or will be discarded if the frame ends
|
||||||
|
* without any output. */
|
||||||
|
size_t frame_pos;
|
||||||
|
char frame[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void vty_push_context(struct vty *vty, int node, uint64_t id)
|
static inline void vty_push_context(struct vty *vty, int node, uint64_t id)
|
||||||
@ -247,7 +253,16 @@ extern void vty_terminate(void);
|
|||||||
extern void vty_reset(void);
|
extern void vty_reset(void);
|
||||||
extern struct vty *vty_new(void);
|
extern struct vty *vty_new(void);
|
||||||
extern struct vty *vty_stdio(void (*atclose)(int isexit));
|
extern struct vty *vty_stdio(void (*atclose)(int isexit));
|
||||||
|
|
||||||
|
/* - vty_frame() output goes to a buffer (for context-begin markers)
|
||||||
|
* - vty_out() will first print this buffer, and clear it
|
||||||
|
* - vty_endframe() clears the buffer without printing it, and prints an
|
||||||
|
* extra string if the buffer was empty before (for context-end markers)
|
||||||
|
*/
|
||||||
extern int vty_out(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
|
extern int vty_out(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||||
|
extern void vty_frame(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||||
|
extern void vty_endframe(struct vty *, const char *);
|
||||||
|
|
||||||
extern void vty_read_config(const char *, char *);
|
extern void vty_read_config(const char *, char *);
|
||||||
extern void vty_time_print(struct vty *, int);
|
extern void vty_time_print(struct vty *, int);
|
||||||
extern void vty_serv_sock(const char *, unsigned short, const char *);
|
extern void vty_serv_sock(const char *, unsigned short, const char *);
|
||||||
|
@ -854,7 +854,7 @@ static int interface_config_write(struct vty *vty)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
||||||
vty_out (vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out (vty, " description %s\n", ifp->desc);
|
vty_out (vty, " description %s\n", ifp->desc);
|
||||||
|
|
||||||
@ -913,7 +913,7 @@ static int interface_config_write(struct vty *vty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vty_out (vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1755,7 +1755,7 @@ static int config_write_ospf6_interface(struct vty *vty)
|
|||||||
if (oi == NULL)
|
if (oi == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vty_out(vty, "interface %s\n", oi->interface->name);
|
vty_frame(vty, "interface %s\n", oi->interface->name);
|
||||||
|
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out(vty, " description %s\n", ifp->desc);
|
vty_out(vty, " description %s\n", ifp->desc);
|
||||||
@ -1808,7 +1808,7 @@ static int config_write_ospf6_interface(struct vty *vty)
|
|||||||
|
|
||||||
ospf6_bfd_write_config(vty, oi);
|
ospf6_bfd_write_config(vty, oi);
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8156,8 +8156,8 @@ static int config_write_interface(struct vty *vty)
|
|||||||
if (ifp->ifindex == IFINDEX_DELETED)
|
if (ifp->ifindex == IFINDEX_DELETED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_frame(vty, "!\n");
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out(vty, " description %s\n", ifp->desc);
|
vty_out(vty, " description %s\n", ifp->desc);
|
||||||
|
|
||||||
@ -8371,6 +8371,8 @@ static int config_write_interface(struct vty *vty)
|
|||||||
} while (rn);
|
} while (rn);
|
||||||
|
|
||||||
ospf_opaque_config_write_if(vty, ifp);
|
ospf_opaque_config_write_if(vty, ifp);
|
||||||
|
|
||||||
|
vty_endframe(vty, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
|
@ -255,7 +255,7 @@ int pim_interface_config_write(struct vty *vty)
|
|||||||
|
|
||||||
/* IF name */
|
/* IF name */
|
||||||
if (vrf->vrf_id == VRF_DEFAULT)
|
if (vrf->vrf_id == VRF_DEFAULT)
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
else
|
else
|
||||||
vty_out(vty, "interface %s vrf %s\n", ifp->name,
|
vty_out(vty, "interface %s vrf %s\n", ifp->name,
|
||||||
vrf->name);
|
vrf->name);
|
||||||
@ -363,7 +363,7 @@ int pim_interface_config_write(struct vty *vty)
|
|||||||
pim_static_write_mroute(pim, vty, ifp);
|
pim_static_write_mroute(pim, vty, ifp);
|
||||||
pim_bfd_write_config(vty, ifp);
|
pim_bfd_write_config(vty, ifp);
|
||||||
}
|
}
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
++writes;
|
++writes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1751,7 +1751,7 @@ static int rip_interface_config_write(struct vty *vty)
|
|||||||
&& (!ri->auth_str) && (!ri->key_chain))
|
&& (!ri->auth_str) && (!ri->key_chain))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
|
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out(vty, " description %s\n", ifp->desc);
|
vty_out(vty, " description %s\n", ifp->desc);
|
||||||
@ -1807,7 +1807,7 @@ static int rip_interface_config_write(struct vty *vty)
|
|||||||
vty_out(vty, " ip rip authentication key-chain %s\n",
|
vty_out(vty, " ip rip authentication key-chain %s\n",
|
||||||
ri->key_chain);
|
ri->key_chain);
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1084,7 +1084,7 @@ static int interface_config_write(struct vty *vty)
|
|||||||
&& (ri->split_horizon == ri->split_horizon_default))
|
&& (ri->split_horizon == ri->split_horizon_default))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out(vty, " description %s\n", ifp->desc);
|
vty_out(vty, " description %s\n", ifp->desc);
|
||||||
|
|
||||||
@ -1105,7 +1105,7 @@ static int interface_config_write(struct vty *vty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
|
|
||||||
write++;
|
write++;
|
||||||
}
|
}
|
||||||
|
@ -2295,12 +2295,12 @@ int vtysh_write_config_integrated(void)
|
|||||||
|
|
||||||
fprintf(stdout, "Building Configuration...\n");
|
fprintf(stdout, "Building Configuration...\n");
|
||||||
|
|
||||||
backup_config_file(quagga_config);
|
backup_config_file(frr_config);
|
||||||
fp = fopen(quagga_config, "w");
|
fp = fopen(frr_config, "w");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
"%% Error: failed to open configuration file %s: %s\n",
|
"%% Error: failed to open configuration file %s: %s\n",
|
||||||
quagga_config, safe_strerror(errno));
|
frr_config, safe_strerror(errno));
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
}
|
||||||
fd = fileno(fp);
|
fd = fileno(fp);
|
||||||
@ -2313,7 +2313,7 @@ int vtysh_write_config_integrated(void)
|
|||||||
|
|
||||||
if (fchmod(fd, CONFIGFILE_MASK) != 0) {
|
if (fchmod(fd, CONFIGFILE_MASK) != 0) {
|
||||||
printf("%% Warning: can't chmod configuration file %s: %s\n",
|
printf("%% Warning: can't chmod configuration file %s: %s\n",
|
||||||
quagga_config, safe_strerror(errno));
|
frr_config, safe_strerror(errno));
|
||||||
err++;
|
err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2345,18 +2345,18 @@ int vtysh_write_config_integrated(void)
|
|||||||
if ((uid != (uid_t)-1 || gid != (gid_t)-1)
|
if ((uid != (uid_t)-1 || gid != (gid_t)-1)
|
||||||
&& fchown(fd, uid, gid)) {
|
&& fchown(fd, uid, gid)) {
|
||||||
printf("%% Warning: can't chown configuration file %s: %s\n",
|
printf("%% Warning: can't chown configuration file %s: %s\n",
|
||||||
quagga_config, safe_strerror(errno));
|
frr_config, safe_strerror(errno));
|
||||||
err++;
|
err++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("%% Warning: stat() failed on %s: %s\n", quagga_config,
|
printf("%% Warning: stat() failed on %s: %s\n", frr_config,
|
||||||
safe_strerror(errno));
|
safe_strerror(errno));
|
||||||
err++;
|
err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
printf("Integrated configuration saved to %s\n", quagga_config);
|
printf("Integrated configuration saved to %s\n", frr_config);
|
||||||
if (err)
|
if (err)
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|
||||||
@ -2370,7 +2370,7 @@ static bool want_config_integrated(void)
|
|||||||
|
|
||||||
switch (vtysh_write_integrated) {
|
switch (vtysh_write_integrated) {
|
||||||
case WRITE_INTEGRATED_UNSPECIFIED:
|
case WRITE_INTEGRATED_UNSPECIFIED:
|
||||||
if (stat(quagga_config, &s) && errno == ENOENT)
|
if (stat(frr_config, &s) && errno == ENOENT)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
case WRITE_INTEGRATED_NO:
|
case WRITE_INTEGRATED_NO:
|
||||||
@ -2712,7 +2712,7 @@ static int vtysh_connect(struct vtysh_client *vclient)
|
|||||||
|
|
||||||
if (!vclient->path[0])
|
if (!vclient->path[0])
|
||||||
snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
|
snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
|
||||||
vty_sock_path, vclient->name);
|
vtydir, vclient->name);
|
||||||
path = vclient->path;
|
path = vclient->path;
|
||||||
|
|
||||||
/* Stat socket to see if we have permission to access it. */
|
/* Stat socket to see if we have permission to access it. */
|
||||||
@ -2806,7 +2806,7 @@ static void vtysh_update_all_insances(struct vtysh_client *head_client)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* ls vty_sock_dir and look for all files ending in .vty */
|
/* ls vty_sock_dir and look for all files ending in .vty */
|
||||||
dir = opendir(vty_sock_path);
|
dir = opendir(vtydir);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
while ((file = readdir(dir)) != NULL) {
|
while ((file = readdir(dir)) != NULL) {
|
||||||
if (begins_with(file->d_name, "ospfd-")
|
if (begins_with(file->d_name, "ospfd-")
|
||||||
@ -2814,7 +2814,7 @@ static void vtysh_update_all_insances(struct vtysh_client *head_client)
|
|||||||
if (n == MAXIMUM_INSTANCES) {
|
if (n == MAXIMUM_INSTANCES) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Parsing %s, client limit(%d) reached!\n",
|
"Parsing %s, client limit(%d) reached!\n",
|
||||||
vty_sock_path, n);
|
vtydir, n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
client = (struct vtysh_client *)malloc(
|
client = (struct vtysh_client *)malloc(
|
||||||
@ -2823,7 +2823,7 @@ static void vtysh_update_all_insances(struct vtysh_client *head_client)
|
|||||||
client->name = "ospfd";
|
client->name = "ospfd";
|
||||||
client->flag = VTYSH_OSPFD;
|
client->flag = VTYSH_OSPFD;
|
||||||
snprintf(client->path, sizeof(client->path),
|
snprintf(client->path, sizeof(client->path),
|
||||||
"%s/%s", vty_sock_path, file->d_name);
|
"%s/%s", vtydir, file->d_name);
|
||||||
client->next = NULL;
|
client->next = NULL;
|
||||||
vtysh_client_sorted_insert(head_client, client);
|
vtysh_client_sorted_insert(head_client, client);
|
||||||
n++;
|
n++;
|
||||||
|
@ -49,10 +49,6 @@ DECLARE_MGROUP(MVTYSH)
|
|||||||
#define VTYSH_NS VTYSH_ZEBRA
|
#define VTYSH_NS VTYSH_ZEBRA
|
||||||
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD
|
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD
|
||||||
|
|
||||||
/* vtysh local configuration file. */
|
|
||||||
#define VTYSH_DEFAULT_CONFIG "vtysh.conf"
|
|
||||||
#define FRR_DEFAULT_CONFIG "frr.conf"
|
|
||||||
|
|
||||||
enum vtysh_write_integrated {
|
enum vtysh_write_integrated {
|
||||||
WRITE_INTEGRATED_UNSPECIFIED,
|
WRITE_INTEGRATED_UNSPECIFIED,
|
||||||
WRITE_INTEGRATED_NO,
|
WRITE_INTEGRATED_NO,
|
||||||
@ -61,7 +57,8 @@ enum vtysh_write_integrated {
|
|||||||
|
|
||||||
extern enum vtysh_write_integrated vtysh_write_integrated;
|
extern enum vtysh_write_integrated vtysh_write_integrated;
|
||||||
|
|
||||||
extern char *quagga_config;
|
extern char frr_config[];
|
||||||
|
extern char vtydir[];
|
||||||
|
|
||||||
void vtysh_init_vty(void);
|
void vtysh_init_vty(void);
|
||||||
void vtysh_init_cmd(void);
|
void vtysh_init_cmd(void);
|
||||||
@ -93,11 +90,12 @@ void vtysh_config_init(void);
|
|||||||
|
|
||||||
void vtysh_pager_init(void);
|
void vtysh_pager_init(void);
|
||||||
|
|
||||||
|
void suid_on(void);
|
||||||
|
void suid_off(void);
|
||||||
|
|
||||||
/* Child process execution flag. */
|
/* Child process execution flag. */
|
||||||
extern int execute_flag;
|
extern int execute_flag;
|
||||||
|
|
||||||
extern struct vty *vty;
|
extern struct vty *vty;
|
||||||
|
|
||||||
extern const char *vty_sock_path;
|
|
||||||
|
|
||||||
#endif /* VTYSH_H */
|
#endif /* VTYSH_H */
|
||||||
|
@ -44,18 +44,22 @@
|
|||||||
/* VTY shell program name. */
|
/* VTY shell program name. */
|
||||||
char *progname;
|
char *progname;
|
||||||
|
|
||||||
|
/* SUID mode */
|
||||||
|
static uid_t elevuid, realuid;
|
||||||
|
static gid_t elevgid, realgid;
|
||||||
|
|
||||||
|
#define VTYSH_CONFIG_NAME "vtysh.conf"
|
||||||
|
#define FRR_CONFIG_NAME "frr.conf"
|
||||||
|
|
||||||
/* Configuration file name and directory. */
|
/* Configuration file name and directory. */
|
||||||
static char vtysh_config_always[MAXPATHLEN] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
|
static char vtysh_config[MAXPATHLEN];
|
||||||
static char quagga_config_default[MAXPATHLEN] = SYSCONFDIR FRR_DEFAULT_CONFIG;
|
char frr_config[MAXPATHLEN];
|
||||||
char *quagga_config = quagga_config_default;
|
char vtydir[MAXPATHLEN];
|
||||||
char history_file[MAXPATHLEN];
|
static char history_file[MAXPATHLEN];
|
||||||
|
|
||||||
/* Flag for indicate executing child command. */
|
/* Flag for indicate executing child command. */
|
||||||
int execute_flag = 0;
|
int execute_flag = 0;
|
||||||
|
|
||||||
/* VTY Socket prefix */
|
|
||||||
const char *vty_sock_path = NULL;
|
|
||||||
|
|
||||||
/* For sigsetjmp() & siglongjmp(). */
|
/* For sigsetjmp() & siglongjmp(). */
|
||||||
static sigjmp_buf jmpbuf;
|
static sigjmp_buf jmpbuf;
|
||||||
|
|
||||||
@ -145,6 +149,7 @@ static void usage(int status)
|
|||||||
"-m, --markfile Mark input file with context end\n"
|
"-m, --markfile Mark input file with context end\n"
|
||||||
" --vty_socket Override vty socket path\n"
|
" --vty_socket Override vty socket path\n"
|
||||||
" --config_dir Override config directory path\n"
|
" --config_dir Override config directory path\n"
|
||||||
|
"-N --pathspace Insert prefix into config & socket paths\n"
|
||||||
"-w, --writeconfig Write integrated config (frr.conf) and exit\n"
|
"-w, --writeconfig Write integrated config (frr.conf) and exit\n"
|
||||||
"-h, --help Display this help and exit\n\n"
|
"-h, --help Display this help and exit\n\n"
|
||||||
"Note that multiple commands may be executed from the command\n"
|
"Note that multiple commands may be executed from the command\n"
|
||||||
@ -174,6 +179,7 @@ struct option longopts[] = {
|
|||||||
{"noerror", no_argument, NULL, 'n'},
|
{"noerror", no_argument, NULL, 'n'},
|
||||||
{"mark", no_argument, NULL, 'm'},
|
{"mark", no_argument, NULL, 'm'},
|
||||||
{"writeconfig", no_argument, NULL, 'w'},
|
{"writeconfig", no_argument, NULL, 'w'},
|
||||||
|
{"pathspace", no_argument, NULL, 'N'},
|
||||||
{0}};
|
{0}};
|
||||||
|
|
||||||
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
|
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
|
||||||
@ -249,6 +255,30 @@ static void vtysh_unflock_config(void)
|
|||||||
close(flock_fd);
|
close(flock_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void suid_on(void)
|
||||||
|
{
|
||||||
|
if (elevuid != realuid && seteuid(elevuid)) {
|
||||||
|
perror("seteuid(on)");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (elevgid != realgid && setegid(elevgid)) {
|
||||||
|
perror("setegid(on)");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void suid_off(void)
|
||||||
|
{
|
||||||
|
if (elevuid != realuid && seteuid(realuid)) {
|
||||||
|
perror("seteuid(off)");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (elevgid != realgid && setegid(realgid)) {
|
||||||
|
perror("setegid(off)");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* VTY shell main routine. */
|
/* VTY shell main routine. */
|
||||||
int main(int argc, char **argv, char **env)
|
int main(int argc, char **argv, char **env)
|
||||||
{
|
{
|
||||||
@ -258,7 +288,6 @@ int main(int argc, char **argv, char **env)
|
|||||||
int boot_flag = 0;
|
int boot_flag = 0;
|
||||||
const char *daemon_name = NULL;
|
const char *daemon_name = NULL;
|
||||||
const char *inputfile = NULL;
|
const char *inputfile = NULL;
|
||||||
const char *vtysh_configfile_name;
|
|
||||||
struct cmd_rec {
|
struct cmd_rec {
|
||||||
char *line;
|
char *line;
|
||||||
struct cmd_rec *next;
|
struct cmd_rec *next;
|
||||||
@ -270,16 +299,22 @@ int main(int argc, char **argv, char **env)
|
|||||||
int writeconfig = 0;
|
int writeconfig = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *homedir = NULL;
|
char *homedir = NULL;
|
||||||
|
int ditch_suid = 0;
|
||||||
|
char sysconfdir[MAXPATHLEN];
|
||||||
|
char pathspace[MAXPATHLEN] = "";
|
||||||
|
|
||||||
/* check for restricted functionality if vtysh is run setuid */
|
/* SUID: drop down to calling user & go back up when needed */
|
||||||
int restricted = (getuid() != geteuid()) || (getgid() != getegid());
|
elevuid = geteuid();
|
||||||
|
elevgid = getegid();
|
||||||
|
realuid = getuid();
|
||||||
|
realgid = getgid();
|
||||||
|
suid_off();
|
||||||
|
|
||||||
/* Preserve name of myself. */
|
/* Preserve name of myself. */
|
||||||
progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
/* if logging open now */
|
strlcpy(sysconfdir, frr_sysconfdir, sizeof(sysconfdir));
|
||||||
if ((p = getenv("VTYSH_LOG")) != NULL)
|
strlcpy(vtydir, frr_vtydir, sizeof(vtydir));
|
||||||
logfile = fopen(p, "a");
|
|
||||||
|
|
||||||
/* Option handling. */
|
/* Option handling. */
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -307,63 +342,20 @@ int main(int argc, char **argv, char **env)
|
|||||||
tail = cr;
|
tail = cr;
|
||||||
} break;
|
} break;
|
||||||
case OPTION_VTYSOCK:
|
case OPTION_VTYSOCK:
|
||||||
vty_sock_path = optarg;
|
ditch_suid = 1; /* option disables SUID */
|
||||||
|
strlcpy(vtydir, optarg, sizeof(vtydir));
|
||||||
break;
|
break;
|
||||||
case OPTION_CONFDIR:
|
case OPTION_CONFDIR:
|
||||||
/*
|
ditch_suid = 1; /* option disables SUID */
|
||||||
* Skip option for Config Directory if setuid
|
strlcpy(sysconfdir, optarg, sizeof(sysconfdir));
|
||||||
*/
|
break;
|
||||||
if (restricted) {
|
case 'N':
|
||||||
|
if (strchr(optarg, '/') || strchr(optarg, '.')) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Overriding of Config Directory blocked for vtysh with setuid");
|
"slashes or dots are not permitted in the --pathspace option.\n");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
/*
|
snprintf(pathspace, sizeof(pathspace), "/%s", optarg);
|
||||||
* Overwrite location for vtysh.conf
|
|
||||||
*/
|
|
||||||
vtysh_configfile_name =
|
|
||||||
strrchr(VTYSH_DEFAULT_CONFIG, '/');
|
|
||||||
if (vtysh_configfile_name)
|
|
||||||
/* skip '/' */
|
|
||||||
vtysh_configfile_name++;
|
|
||||||
else
|
|
||||||
/*
|
|
||||||
* VTYSH_DEFAULT_CONFIG configured with relative
|
|
||||||
* path
|
|
||||||
* during config? Should really never happen for
|
|
||||||
* sensible config
|
|
||||||
*/
|
|
||||||
vtysh_configfile_name =
|
|
||||||
(char *)VTYSH_DEFAULT_CONFIG;
|
|
||||||
strlcpy(vtysh_config_always, optarg,
|
|
||||||
sizeof(vtysh_config_always));
|
|
||||||
strlcat(vtysh_config_always, "/",
|
|
||||||
sizeof(vtysh_config_always));
|
|
||||||
strlcat(vtysh_config_always, vtysh_configfile_name,
|
|
||||||
sizeof(vtysh_config_always));
|
|
||||||
/*
|
|
||||||
* Overwrite location for frr.conf
|
|
||||||
*/
|
|
||||||
vtysh_configfile_name =
|
|
||||||
strrchr(FRR_DEFAULT_CONFIG, '/');
|
|
||||||
if (vtysh_configfile_name)
|
|
||||||
/* skip '/' */
|
|
||||||
vtysh_configfile_name++;
|
|
||||||
else
|
|
||||||
/*
|
|
||||||
* FRR_DEFAULT_CONFIG configured with relative
|
|
||||||
* path
|
|
||||||
* during config? Should really never happen for
|
|
||||||
* sensible config
|
|
||||||
*/
|
|
||||||
vtysh_configfile_name =
|
|
||||||
(char *)FRR_DEFAULT_CONFIG;
|
|
||||||
strlcpy(quagga_config_default, optarg,
|
|
||||||
sizeof(vtysh_config_always));
|
|
||||||
strlcat(quagga_config_default, "/",
|
|
||||||
sizeof(vtysh_config_always));
|
|
||||||
strlcat(quagga_config_default, vtysh_configfile_name,
|
|
||||||
sizeof(quagga_config_default));
|
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
daemon_name = optarg;
|
daemon_name = optarg;
|
||||||
@ -395,8 +387,10 @@ int main(int argc, char **argv, char **env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vty_sock_path)
|
if (ditch_suid) {
|
||||||
vty_sock_path = frr_vtydir;
|
elevuid = realuid;
|
||||||
|
elevgid = realgid;
|
||||||
|
}
|
||||||
|
|
||||||
if (markfile + writeconfig + dryrun + boot_flag > 1) {
|
if (markfile + writeconfig + dryrun + boot_flag > 1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -410,6 +404,12 @@ int main(int argc, char **argv, char **env)
|
|||||||
"NOT SUPPORTED since its\nresults are inconsistent!\n");
|
"NOT SUPPORTED since its\nresults are inconsistent!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snprintf(vtysh_config, sizeof(vtysh_config), "%s%s/%s",
|
||||||
|
sysconfdir, pathspace, VTYSH_CONFIG_NAME);
|
||||||
|
snprintf(frr_config, sizeof(frr_config), "%s%s/%s",
|
||||||
|
sysconfdir, pathspace, FRR_CONFIG_NAME);
|
||||||
|
strlcat(vtydir, pathspace, sizeof(vtydir));
|
||||||
|
|
||||||
/* Initialize user input buffer. */
|
/* Initialize user input buffer. */
|
||||||
line_read = NULL;
|
line_read = NULL;
|
||||||
setlinebuf(stdout);
|
setlinebuf(stdout);
|
||||||
@ -425,8 +425,11 @@ int main(int argc, char **argv, char **env)
|
|||||||
|
|
||||||
vty_init_vtysh();
|
vty_init_vtysh();
|
||||||
|
|
||||||
/* Read vtysh configuration file before connecting to daemons. */
|
/* Read vtysh configuration file before connecting to daemons.
|
||||||
vtysh_read_config(vtysh_config_always);
|
* (file may not be readable to calling user in SUID mode) */
|
||||||
|
suid_on();
|
||||||
|
vtysh_read_config(vtysh_config);
|
||||||
|
suid_off();
|
||||||
|
|
||||||
if (markfile) {
|
if (markfile) {
|
||||||
if (!inputfile) {
|
if (!inputfile) {
|
||||||
@ -442,7 +445,7 @@ int main(int argc, char **argv, char **env)
|
|||||||
if (inputfile) {
|
if (inputfile) {
|
||||||
ret = vtysh_read_config(inputfile);
|
ret = vtysh_read_config(inputfile);
|
||||||
} else {
|
} else {
|
||||||
ret = vtysh_read_config(quagga_config_default);
|
ret = vtysh_read_config(frr_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(ret);
|
exit(ret);
|
||||||
@ -486,6 +489,9 @@ int main(int argc, char **argv, char **env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SUID: go back up elevated privs */
|
||||||
|
suid_on();
|
||||||
|
|
||||||
/* Make sure we pass authentication before proceeding. */
|
/* Make sure we pass authentication before proceeding. */
|
||||||
vtysh_auth();
|
vtysh_auth();
|
||||||
|
|
||||||
@ -498,6 +504,9 @@ int main(int argc, char **argv, char **env)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SUID: back down, don't need privs further on */
|
||||||
|
suid_off();
|
||||||
|
|
||||||
if (writeconfig) {
|
if (writeconfig) {
|
||||||
vtysh_execute("enable");
|
vtysh_execute("enable");
|
||||||
return vtysh_write_config_integrated();
|
return vtysh_write_config_integrated();
|
||||||
@ -531,6 +540,17 @@ int main(int argc, char **argv, char **env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getenv("VTYSH_LOG")) {
|
||||||
|
const char *logpath = getenv("VTYSH_LOG");
|
||||||
|
|
||||||
|
logfile = fopen(logpath, "a");
|
||||||
|
if (!logfile) {
|
||||||
|
fprintf(stderr, "Failed to open logfile (%s): %s\n",
|
||||||
|
logpath, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If eval mode. */
|
/* If eval mode. */
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
/* Enter into enable node. */
|
/* Enter into enable node. */
|
||||||
@ -592,13 +612,13 @@ int main(int argc, char **argv, char **env)
|
|||||||
|
|
||||||
/* Boot startup configuration file. */
|
/* Boot startup configuration file. */
|
||||||
if (boot_flag) {
|
if (boot_flag) {
|
||||||
vtysh_flock_config(quagga_config);
|
vtysh_flock_config(frr_config);
|
||||||
int ret = vtysh_read_config(quagga_config);
|
int ret = vtysh_read_config(frr_config);
|
||||||
vtysh_unflock_config();
|
vtysh_unflock_config();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Configuration file[%s] processing failure: %d\n",
|
"Configuration file[%s] processing failure: %d\n",
|
||||||
quagga_config, ret);
|
frr_config, ret);
|
||||||
if (no_error)
|
if (no_error)
|
||||||
exit(0);
|
exit(0);
|
||||||
else
|
else
|
||||||
|
@ -2793,7 +2793,7 @@ static int if_config_write(struct vty *vty)
|
|||||||
vrf = vrf_lookup_by_id(ifp->vrf_id);
|
vrf = vrf_lookup_by_id(ifp->vrf_id);
|
||||||
|
|
||||||
if (ifp->vrf_id == VRF_DEFAULT)
|
if (ifp->vrf_id == VRF_DEFAULT)
|
||||||
vty_out(vty, "interface %s\n", ifp->name);
|
vty_frame(vty, "interface %s\n", ifp->name);
|
||||||
else
|
else
|
||||||
vty_out(vty, "interface %s vrf %s\n", ifp->name,
|
vty_out(vty, "interface %s vrf %s\n", ifp->name,
|
||||||
vrf->name);
|
vrf->name);
|
||||||
@ -2844,7 +2844,7 @@ static int if_config_write(struct vty *vty)
|
|||||||
|
|
||||||
link_params_config_write(vty, ifp);
|
link_params_config_write(vty, ifp);
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_endframe(vty, "!\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user