mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 16:57:43 +00:00
Merge pull request #233 from donaldsharp/ecmp1
bgpd, zebra: Allow setting ecmp from daemon cli
This commit is contained in:
commit
83456d1438
@ -75,6 +75,7 @@ static const struct option longopts[] =
|
||||
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
|
||||
{ "retain", no_argument, NULL, 'r'},
|
||||
{ "no_kernel", no_argument, NULL, 'n'},
|
||||
{ "ecmp", required_argument, NULL, 'e'},
|
||||
{ "user", required_argument, NULL, 'u'},
|
||||
{ "group", required_argument, NULL, 'g'},
|
||||
{ "skip_runas", no_argument, NULL, 'S'},
|
||||
@ -176,6 +177,7 @@ redistribution between different routing protocols.\n\n\
|
||||
--vty_socket Override vty socket path\n\
|
||||
-r, --retain When program terminates, retain added route by bgpd.\n\
|
||||
-n, --no_kernel Do not install route to kernel.\n\
|
||||
-e, --ecmp Specify ECMP to use.\n\
|
||||
-u, --user User to run as\n\
|
||||
-g, --group Group to run as\n\
|
||||
-S, --skip_runas Skip user and group run as\n\
|
||||
@ -468,6 +470,14 @@ main (int argc, char **argv)
|
||||
case 'A':
|
||||
vty_addr = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
multipath_num = atoi (optarg);
|
||||
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
|
||||
{
|
||||
zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
/* Deal with atoi() returning 0 on failure, and bgpd not
|
||||
listening on bgp port... */
|
||||
|
@ -84,11 +84,11 @@ bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi,
|
||||
switch (peertype)
|
||||
{
|
||||
case BGP_PEER_IBGP:
|
||||
bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM;
|
||||
bgp->maxpaths[afi][safi].maxpaths_ibgp = multipath_num;
|
||||
bgp->maxpaths[afi][safi].ibgp_flags = 0;
|
||||
break;
|
||||
case BGP_PEER_EBGP:
|
||||
bgp->maxpaths[afi][safi].maxpaths_ebgp = MULTIPATH_NUM;
|
||||
bgp->maxpaths[afi][safi].maxpaths_ebgp = multipath_num;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
@ -436,7 +436,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
|
||||
char path_buf[PATH_ADDPATH_STR_BUFFER];
|
||||
|
||||
mpath_changed = 0;
|
||||
maxpaths = MULTIPATH_NUM;
|
||||
maxpaths = multipath_num;
|
||||
mpath_count = 0;
|
||||
cur_mpath = NULL;
|
||||
old_mpath_count = 0;
|
||||
|
@ -1144,6 +1144,13 @@ bgp_maxpaths_config_vty (struct vty *vty, int peer_type, const char *mpaths,
|
||||
if (set)
|
||||
{
|
||||
maxpaths = strtol(mpaths, NULL, 10);
|
||||
if (maxpaths > multipath_num)
|
||||
{
|
||||
vty_out (vty,
|
||||
"%% Maxpaths Specified: %d is > than multipath num specified on bgp command line %d",
|
||||
maxpaths, multipath_num);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ret = bgp_maximum_paths_set (bgp, afi, safi, peer_type, maxpaths, options);
|
||||
}
|
||||
else
|
||||
|
@ -69,7 +69,7 @@ struct stream *bgp_ifindices_buf = NULL;
|
||||
Number of supported next-hops are finite, use of arrays should be ok. */
|
||||
struct attr attr_cp[MULTIPATH_NUM];
|
||||
struct attr_extra attr_extra_cp[MULTIPATH_NUM];
|
||||
int attr_index = 0;
|
||||
unsigned int attr_index = 0;
|
||||
|
||||
/* Once per address-family initialization of the attribute array */
|
||||
#define BGP_INFO_ATTR_BUF_INIT()\
|
||||
@ -82,7 +82,7 @@ do {\
|
||||
#define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
|
||||
do { \
|
||||
*info_dst = *info_src; \
|
||||
assert(attr_index != MULTIPATH_NUM);\
|
||||
assert(attr_index != multipath_num);\
|
||||
attr_cp[attr_index].extra = &attr_extra_cp[attr_index]; \
|
||||
bgp_attr_dup (&attr_cp[attr_index], info_src->attr); \
|
||||
bgp_attr_deep_dup (&attr_cp[attr_index], info_src->attr); \
|
||||
|
@ -93,6 +93,8 @@ struct bgp_master *bm;
|
||||
/* BGP community-list. */
|
||||
struct community_list_handler *bgp_clist;
|
||||
|
||||
unsigned int multipath_num = MULTIPATH_NUM;
|
||||
|
||||
static void bgp_if_init (struct bgp *bgp);
|
||||
static void bgp_if_finish (struct bgp *bgp);
|
||||
|
||||
@ -2918,8 +2920,8 @@ bgp_create (as_t *as, const char *name, enum bgp_instance_type inst_type)
|
||||
bgp->rib[afi][safi] = bgp_table_init (afi, safi);
|
||||
|
||||
/* Enable maximum-paths */
|
||||
bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_EBGP, MULTIPATH_NUM, 0);
|
||||
bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_IBGP, MULTIPATH_NUM, 0);
|
||||
bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_EBGP, multipath_num, 0);
|
||||
bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_IBGP, multipath_num, 0);
|
||||
}
|
||||
|
||||
bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
|
||||
|
@ -1161,6 +1161,7 @@ typedef enum
|
||||
} bgp_policy_type_e;
|
||||
|
||||
extern struct bgp_master *bm;
|
||||
extern unsigned int multipath_num;
|
||||
|
||||
/* Prototypes. */
|
||||
extern void bgp_terminate (void);
|
||||
|
11
zebra/main.c
11
zebra/main.c
@ -96,6 +96,7 @@ struct option longopts[] =
|
||||
{ "vty_addr", required_argument, NULL, 'A'},
|
||||
{ "vty_port", required_argument, NULL, 'P'},
|
||||
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
|
||||
{ "ecmp", required_argument, NULL, 'e'},
|
||||
{ "retain", no_argument, NULL, 'r'},
|
||||
{ "dryrun", no_argument, NULL, 'C'},
|
||||
#ifdef HAVE_NETLINK
|
||||
@ -135,6 +136,8 @@ char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
|
||||
/* Process ID saved for use by init system */
|
||||
const char *pid_file = PATH_ZEBRA_PID;
|
||||
|
||||
unsigned int multipath_num = MULTIPATH_NUM;
|
||||
|
||||
/* Help information display. */
|
||||
static void
|
||||
usage (char *progname, int status)
|
||||
@ -328,6 +331,14 @@ main (int argc, char **argv)
|
||||
case 'A':
|
||||
vty_addr = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
multipath_num = atoi (optarg);
|
||||
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
|
||||
{
|
||||
zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
pid_file = optarg;
|
||||
break;
|
||||
|
@ -1108,7 +1108,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
struct sockaddr_nl snl;
|
||||
struct nexthop *nexthop = NULL, *tnexthop;
|
||||
int recursing;
|
||||
int nexthop_num;
|
||||
unsigned int nexthop_num;
|
||||
int discard;
|
||||
int family = PREFIX_FAMILY(p);
|
||||
const char *routedesc;
|
||||
@ -1224,7 +1224,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
}
|
||||
|
||||
/* Singlepath case. */
|
||||
if (nexthop_num == 1 || MULTIPATH_NUM == 1)
|
||||
if (nexthop_num == 1 || multipath_num == 1)
|
||||
{
|
||||
nexthop_num = 0;
|
||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
||||
@ -1300,7 +1300,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
nexthop_num = 0;
|
||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
||||
{
|
||||
if (nexthop_num >= MULTIPATH_NUM)
|
||||
if (nexthop_num >= multipath_num)
|
||||
break;
|
||||
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||
@ -1457,7 +1457,7 @@ netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp)
|
||||
mpls_lse_t lse;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
struct nexthop *nexthop = NULL;
|
||||
int nexthop_num;
|
||||
unsigned int nexthop_num;
|
||||
const char *routedesc;
|
||||
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
|
||||
|
||||
@ -1521,7 +1521,7 @@ netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp)
|
||||
/* Fill nexthops (paths) based on single-path or multipath. The paths
|
||||
* chosen depend on the operation.
|
||||
*/
|
||||
if (nexthop_num == 1 || MULTIPATH_NUM == 1)
|
||||
if (nexthop_num == 1 || multipath_num == 1)
|
||||
{
|
||||
routedesc = "single hop";
|
||||
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
|
||||
@ -1579,7 +1579,7 @@ netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp)
|
||||
if (!nexthop)
|
||||
continue;
|
||||
|
||||
if (MULTIPATH_NUM != 0 && nexthop_num >= MULTIPATH_NUM)
|
||||
if (nexthop_num >= multipath_num)
|
||||
break;
|
||||
|
||||
if ((cmd == RTM_NEWROUTE &&
|
||||
|
@ -137,7 +137,7 @@ typedef struct netlink_route_info_t_
|
||||
u_char af;
|
||||
struct prefix *prefix;
|
||||
uint32_t *metric;
|
||||
int num_nhs;
|
||||
unsigned int num_nhs;
|
||||
|
||||
/*
|
||||
* Nexthop structures
|
||||
@ -289,7 +289,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
||||
|
||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
||||
{
|
||||
if (ri->num_nhs >= MULTIPATH_NUM)
|
||||
if (ri->num_nhs >= multipath_num)
|
||||
break;
|
||||
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||
@ -325,7 +325,7 @@ netlink_route_info_encode (netlink_route_info_t *ri, char *in_buf,
|
||||
size_t in_buf_len)
|
||||
{
|
||||
size_t bytelen;
|
||||
int nexthop_num = 0;
|
||||
unsigned int nexthop_num = 0;
|
||||
size_t buf_offset;
|
||||
netlink_nh_info_t *nhi;
|
||||
|
||||
@ -447,7 +447,7 @@ static void
|
||||
zfpm_log_route_info (netlink_route_info_t *ri, const char *label)
|
||||
{
|
||||
netlink_nh_info_t *nhi;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
zfpm_debug ("%s : %s %s/%d, Proto: %s, Metric: %u", label,
|
||||
nl_msg_type_to_str (ri->nlmsg_type),
|
||||
|
@ -149,7 +149,7 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
int recursing;
|
||||
uint num_nhs, u;
|
||||
struct nexthop *nexthops[MAX (MULTIPATH_NUM, 64)];
|
||||
struct nexthop *nexthops[MULTIPATH_NUM];
|
||||
|
||||
msg = QPB_ALLOC(allocator, typeof(*msg));
|
||||
if (!msg) {
|
||||
@ -198,7 +198,7 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
||||
num_nhs = 0;
|
||||
for (ALL_NEXTHOPS_RO (rib->nexthop, nexthop, tnexthop, recursing))
|
||||
{
|
||||
if (MULTIPATH_NUM != 0 && num_nhs >= MULTIPATH_NUM)
|
||||
if (num_nhs >= multipath_num)
|
||||
break;
|
||||
|
||||
if (num_nhs >= ZEBRA_NUM_OF(nexthops))
|
||||
|
@ -138,7 +138,7 @@ kernel_lsp_cmd (int action, zebra_lsp_t *lsp)
|
||||
if (!nexthop)
|
||||
continue;
|
||||
|
||||
if (MULTIPATH_NUM != 0 && nexthop_num >= MULTIPATH_NUM)
|
||||
if (nexthop_num >= multipath_num)
|
||||
break;
|
||||
|
||||
/* XXX */
|
||||
|
@ -1050,12 +1050,12 @@ zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *
|
||||
void
|
||||
zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsigned int nexthop_num)
|
||||
{
|
||||
if (nexthop_num > MULTIPATH_NUM)
|
||||
if (nexthop_num > multipath_num)
|
||||
{
|
||||
char buff[PREFIX2STR_BUFFER];
|
||||
prefix2str(p, buff, sizeof (buff));
|
||||
zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
|
||||
caller, buff, nexthop_num, MULTIPATH_NUM);
|
||||
caller, buff, nexthop_num, multipath_num);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1274,7 +1274,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb
|
||||
static int
|
||||
zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct stream *s;
|
||||
struct in6_addr nexthop;
|
||||
struct rib *rib;
|
||||
@ -1318,9 +1318,9 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||
* next-hop-addr/next-hop-ifindices. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
||||
{
|
||||
int nh_count = 0;
|
||||
int if_count = 0;
|
||||
int max_nh_if = 0;
|
||||
unsigned int nh_count = 0;
|
||||
unsigned int if_count = 0;
|
||||
unsigned int max_nh_if = 0;
|
||||
|
||||
nexthop_num = stream_getc (s);
|
||||
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
|
||||
@ -1332,12 +1332,12 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||
{
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
stream_get (&nexthop, s, 16);
|
||||
if (nh_count < MULTIPATH_NUM) {
|
||||
if (nh_count < multipath_num) {
|
||||
nexthops[nh_count++] = nexthop;
|
||||
}
|
||||
break;
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
if (if_count < MULTIPATH_NUM) {
|
||||
if (if_count < multipath_num) {
|
||||
ifindices[if_count++] = stream_getl (s);
|
||||
}
|
||||
break;
|
||||
@ -1401,7 +1401,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||
static int
|
||||
zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct stream *s;
|
||||
struct in6_addr nexthop;
|
||||
struct rib *rib;
|
||||
@ -1454,9 +1454,9 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
* next-hop-addr/next-hop-ifindices. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
||||
{
|
||||
int nh_count = 0;
|
||||
int if_count = 0;
|
||||
int max_nh_if = 0;
|
||||
unsigned int nh_count = 0;
|
||||
unsigned int if_count = 0;
|
||||
unsigned int max_nh_if = 0;
|
||||
|
||||
nexthop_num = stream_getc (s);
|
||||
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
|
||||
@ -1468,12 +1468,12 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
stream_get (&nexthop, s, 16);
|
||||
if (nh_count < MULTIPATH_NUM) {
|
||||
if (nh_count < multipath_num) {
|
||||
nexthops[nh_count++] = nexthop;
|
||||
}
|
||||
break;
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
if (if_count < MULTIPATH_NUM) {
|
||||
if (if_count < multipath_num) {
|
||||
ifindices[if_count++] = stream_getl (s);
|
||||
}
|
||||
break;
|
||||
|
@ -135,6 +135,7 @@ struct zebra_t
|
||||
struct work_queue *lsp_process_q;
|
||||
};
|
||||
extern struct zebra_t zebrad;
|
||||
extern unsigned int multipath_num;
|
||||
|
||||
/* Prototypes. */
|
||||
extern void zebra_init (void);
|
||||
|
Loading…
Reference in New Issue
Block a user