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