]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd, zebra: Allow setting ecmp from daemon cli 233/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 3 Nov 2016 23:59:19 +0000 (19:59 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 1 Mar 2017 12:58:32 +0000 (07:58 -0500)
When starting up bgp and zebra now, you can specify
-e <number> or --ecmp <number>
and that number will be used as the maximum ecmp
that can be used.

The <number specified must be >= 1 and <= MULTIPATH_NUM
that Quagga is compiled with.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
13 files changed:
bgpd/bgp_main.c
bgpd/bgp_mpath.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
zebra/main.c
zebra/rt_netlink.c
zebra/zebra_fpm_netlink.c
zebra/zebra_fpm_protobuf.c
zebra/zebra_mpls_openbsd.c
zebra/zserv.c
zebra/zserv.h

index 9607d381d9810230421abf72396ef6f6e5f45a6d..fbbcda59158beee4035b6f4ab4f1aede67ebffc1 100644 (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... */
index f564ff16916df2804745d0983676523bd9d64b0b..a95c4a008efbec984410cae810181734c52a993f 100644 (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;
index aa8c3145f98d1b1283de81786afbd42953beeee1..07f2d5945f31ac09093deaba3b351a7dc8a2b293 100644 (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
index 822f459c28f873c6ac8dd3cda6112e5e9a98c3de..2a513dda25619c60cc43e18f7bf46e3583c50190 100644 (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); \
index 3512167b02ff3f24ffd82fc7309c8f07b00a76ba..9b779e5d3897d4fd49cc0ecfc296bf3024a02bce 100644 (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;
index 09c64aa331396f5dde1fb99b8aec26e79ccb3d95..f0f2ed87bdc79e8c6fddf9a354ae70653f7e6baa 100644 (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);
index 79c9ea7023fedd568d76ea9ff3c6fb488a37a50e..b72ce84cd6b007d4b412ae6846fda62b6736a820 100644 (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;
index d88dc05b2875b531ee62f33d17c0fd4f894b235b..c2bfa70657598dbb917aa84b149a6e74c7f3830d 100644 (file)
@@ -1257,7 +1257,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;
@@ -1373,7 +1373,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))
@@ -1449,7 +1449,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))
@@ -1606,7 +1606,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);
 
@@ -1670,7 +1670,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);
@@ -1728,7 +1728,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 &&
index 9fffc9e611474babd23e240ba34d3689c0d138c5..92ab5df2c38fc17fe50b5aad456b8cd90e5a4eb8 100644 (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),
index 702c355f1acf453d928665aacb0dabafc3ce3006..fba57c68f5bc02b7a9d2ea68971207b13cfc47d7 100644 (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))
index 1127f568c08f775bec73eca5c6af521b7db03a3a..b68b03e0c40394466ed7d7047b0d2cfd2c48e4d1 100644 (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 */
index 29515e9180900eb00067e4f4f3d268b679e5d0c2..60364410a855e937470bb73f0c48e102e75d3f79 100644 (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;
index a5a9979468b28db42cfb6835ec68e4bc6cb97175..21cf1004bf62b33c03399ea2c3273f0b253ccf15 100644 (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);