Merge pull request #233 from donaldsharp/ecmp1

bgpd, zebra: Allow setting ecmp from daemon cli
This commit is contained in:
Renato Westphal 2017-03-03 12:42:52 -03:00 committed by GitHub
commit 83456d1438
13 changed files with 66 additions and 34 deletions

View File

@ -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... */

View File

@ -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;

View File

@ -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

View File

@ -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); \

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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 &&

View File

@ -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),

View File

@ -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))

View File

@ -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 */

View File

@ -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;

View File

@ -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);