Comments inline...
On Thu, Jan 7, 2016 at 8:09 AM, 林守磊 <linxiu...@gmail.com> wrote: > diff --git a/lib/table.h b/lib/table.h > index ab357a0..946fcb2 100644 > --- a/lib/table.h > +++ b/lib/table.h > @@ -53,6 +53,7 @@ struct route_table_delegate_t_ > struct route_table > { > struct route_node *top; > + int tableno; > > /* > * Delegate that performs certain functions for this table. > diff --git a/zebra/rib.h b/zebra/rib.h > index d3a83c6..78df691 100644 > --- a/zebra/rib.h > +++ b/zebra/rib.h > @@ -577,4 +577,24 @@ rib_tables_iter_cleanup (rib_tables_iter_t *iter) > iter->state = RIB_TABLES_ITER_S_DONE; > } > > +typedef enum { false, true } bool; > irrespective of whether or not we want to introduce true/false to the code it does not belong in zebra/rib.h. I would prefer just returning 0/1 and using that instead of true/false enum's. Unless someone would be willing to retrofit the entirety of the code base. > +struct route_table_iter; > + > +struct route_table_iter > +{ > + struct route_table_iter *pre; > + struct route_table_iter *next; > + struct route_table *route_table; > +}; > + > +int vrf_create(int tableno); > +bool vrf_tableno_exists(int tableno); > +int get_table_count(); > + > vrf_create is a poorly named function imo, it should fit in with the current code in quagga.. There is already a zebra_vrf_alloc() and zebra_vrf_table_create(). The code you are working on needs to work in the confines of those functions. Possibly you are working on an old code base? > +#define VRF_FOREACH_TABLE(afi, safi, table) \ > + (table) = vrf_table((afi), (safi), 0);\ > + for (int i = 0, j = get_table_count();\ > + i < j;\ > + i++, (table) = vrf_table((afi), (safi), i)) > + > #endif /*_ZEBRA_RIB_H */ > diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c > index 95a82fd..e94c47e 100644 > --- a/zebra/rt_netlink.c > +++ b/zebra/rt_netlink.c > @@ -685,6 +685,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct > nlmsghdr *h) > return 0; > > table = rtm->rtm_table; > + vrf_create(table); > I don't think that this is the concern of netlink_routing_table. It should be passing the route to zebra_rib.c and zebra_rib.c should do the right thing with it. > #if 0 /* we weed them out later in > rib_weed_tables () */ > if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default) > return 0; > diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c > index dc7e1ca..e00cf83 100644 > --- a/zebra/zebra_rib.c > +++ b/zebra/zebra_rib.c > @@ -122,6 +122,39 @@ vrf_alloc (const char *name) > return vrf; > } > > +static struct vrf* > +vrf_alloc_tableno(const char *name, int tableno) > +{ > + struct vrf *vrf; > + vrf = vrf_alloc(name); > + > + vrf->stable[AFI_IP][SAFI_UNICAST]->tableno = tableno; > + vrf->stable[AFI_IP6][SAFI_UNICAST]->tableno = tableno; > + vrf->stable[AFI_IP][SAFI_MULTICAST]->tableno = tableno; > + vrf->stable[AFI_IP6][SAFI_MULTICAST]->tableno = tableno; > + > + vrf->table[AFI_IP][SAFI_UNICAST]->tableno = tableno; > + vrf->table[AFI_IP6][SAFI_UNICAST]->tableno = tableno; > + vrf->table[AFI_IP][SAFI_MULTICAST]->tableno = tableno; > + vrf->table[AFI_IP6][SAFI_MULTICAST]->tableno = tableno; > + return vrf; > +} > Again this sure looks like code that is already in the latest master. Are you working off of it? > + > +int > +get_vrfid_by_tableno(afi_t afi, safi_t safi, int tableno) > +{ > + if (tableno == 0 || tableno == RT_TABLE_MAIN) > + return 0; > + > + struct route_table *table; > + for (int i = 0; i < vector_count(vrf_vector); i++) > + { > + table = vrf_table(afi, safi, i); > + if (table->tableno == tableno) > + return i; > + } > + return -1; > +} > /* Lookup VRF by identifier. */ > struct vrf * > vrf_lookup (u_int32_t id) > @@ -136,7 +169,7 @@ vrf_init (void) > struct vrf *default_table; > > /* Allocate VRF vector. */ > - vrf_vector = vector_init (1); > + vrf_vector = vector_init (2); > > /* Allocate default main table. */ > default_table = vrf_alloc ("Default-IP-Routing-Table"); > @@ -145,6 +178,43 @@ vrf_init (void) > vector_set_index (vrf_vector, 0, default_table); > } > > +int > +get_table_count() > +{ > + return vector_count(vrf_vector); > +} > + > +int > +vrf_create(int tableno) > +{ > + if (vrf_tableno_exists(tableno)) > + { > + return -1; > + } > + > + unsigned int table_nums = vector_count(vrf_vector); > + struct vrf *table; > + char tablename[40]; > + sprintf(tablename, "%d-IP-Routing-Table", tableno); > + table = vrf_alloc_tableno (tablename, tableno); > + vector_set_index (vrf_vector, table_nums, table); > +} > + > +bool > +vrf_tableno_exists(int tableno) > +{ > + if (tableno == 0 || tableno == RT_TABLE_MAIN) > + return true; > + > + struct route_table *table; > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > + if (table->tableno == tableno) > + return true; > + } > + return false; > +} > + > /* Lookup route table. */ > struct route_table * > vrf_table (afi_t afi, safi_t safi, u_int32_t id) > @@ -484,7 +554,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop > *nexthop, int set, > newhop = match->nexthop; > if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4) > nexthop->ifindex = newhop->ifindex; > - > Whitespace change? > return 1; > } > else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) > @@ -1033,7 +1102,7 @@ nexthop_active_check (struct route_node *rn, struct > rib *rib, > if (RIB_SYSTEM_ROUTE(rib) || > (family == AFI_IP && rn->p.family != AF_INET) || > (family == AFI_IP6 && rn->p.family != AF_INET6)) > - return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); > + return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); > Whitespace change? > > /* The original code didn't determine the family correctly > * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi > @@ -1059,6 +1128,12 @@ nexthop_active_check (struct route_node *rn, struct > rib *rib, > return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); > } > > +void > +print_rib(struct route_node *rn) > +{ > + char buf[INET6_ADDRSTRLEN]; > + inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)); > +} > This function doesn't do anything with the output of inet_ntop, just remove? > /* Iterate over all nexthops of the given RIB entry and refresh their > * ACTIVE flag. rib->nexthop_active_num is updated accordingly. If any > * nexthop is found to toggle the ACTIVE flag, the whole rib structure > @@ -1082,7 +1157,7 @@ nexthop_active_update (struct route_node *rn, struct > rib *rib, int set) > prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); > prev_index = nexthop->ifindex; > if ((new_active = nexthop_active_check (rn, rib, nexthop, set))) > - rib->nexthop_active_num++; > + rib->nexthop_active_num++; > whitespace change? > if (prev_active != new_active || > prev_index != nexthop->ifindex) > SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED); > @@ -1255,6 +1330,7 @@ rib_process (struct route_node *rn) > if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q) > inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); > > + inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); > Why the addition of this line? The exact same thing is done above but protected by the DEBUG guards. > RNODE_FOREACH_RIB_SAFE (rn, rib, next) > { > /* Currently installed rib. */ > @@ -1815,8 +1891,15 @@ rib_add_ipv4 (int type, int flags, struct > prefix_ipv4 *p, > struct route_node *rn; > struct nexthop *nexthop; > > + int id; > + // in this case vrf_id is the real tableno > + // and id is the vector index > + id = get_vrfid_by_tableno(AFI_IP, safi, vrf_id); > + assert(id >= 0); > + > Let's name our variables appropriately here and consistent with the rest of the code base. > + > /* Lookup table. */ > - table = vrf_table (AFI_IP, safi, 0); > + table = vrf_table (AFI_IP, safi, id); > if (! table) > return 0; > > @@ -2154,8 +2237,10 @@ rib_delete_ipv4 (int type, int flags, struct > prefix_ipv4 *p, > char buf1[INET_ADDRSTRLEN]; > char buf2[INET_ADDRSTRLEN]; > > + int id; > + id = get_vrfid_by_tableno(AFI_IP, safi, vrf_id); > /* Lookup table. */ > - table = vrf_table (AFI_IP, safi, 0); > + table = vrf_table (AFI_IP, safi, id); > if (! table) > return 0; > > @@ -2292,10 +2377,25 @@ static_install_ipv4 (struct prefix *p, struct > static_ipv4 *si) > struct route_node *rn; > struct route_table *table; > > - /* Lookup table. */ > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return; > + { > + continue; > + } > + > + if ((zebrad.rtm_table_default == 0 || zebrad.rtm_table_default == > RT_TABLE_MAIN) && \ > + (table->tableno == 0 || table->tableno == RT_TABLE_MAIN) ) { > + ; > + } > + else if (table->tableno == zebrad.rtm_table_default) > + { > + ; > + } > + else > + { > + continue; > + } > > /* Lookup existing route */ > rn = route_node_get (table, p); > @@ -2357,6 +2457,7 @@ static_install_ipv4 (struct prefix *p, struct > static_ipv4 *si) > /* Link this rib to the tree. */ > rib_addnode (rn, rib); > } > + } > } > > static int > @@ -2450,11 +2551,14 @@ static_add_ipv4 (struct prefix *p, struct in_addr > *gate, const char *ifname, > struct static_ipv4 *update = NULL; > struct route_table *stable; > > + // ignore vrf_id, because it is always zero. And it sucks > + vrf_id = get_vrfid_by_tableno(AFI_IP, SAFI_UNICAST, > zebrad.rtm_table_default); > + assert(vrf_id >= 0); > + > /* Lookup table. */ > stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id); > if (! stable) > return -1; > - > /* Lookup static route prefix. */ > rn = route_node_get (stable, p); > > @@ -2630,8 +2734,10 @@ rib_add_ipv6 (int type, int flags, struct > prefix_ipv6 *p, > struct route_node *rn; > struct nexthop *nexthop; > > + int id; > + id = get_vrfid_by_tableno(AFI_IP6, safi, vrf_id); > again, can we name the variables a bit better? In any event, I would highly suggest respinning your code with the latest Quagga, this version is old and won't work properly with the current code base. donald > /* Lookup table. */ > - table = vrf_table (AFI_IP6, safi, 0); > + table = vrf_table (AFI_IP6, safi, id); > if (! table) > return 0; > > @@ -2745,8 +2851,10 @@ rib_delete_ipv6 (int type, int flags, struct > prefix_ipv6 *p, > /* Apply mask. */ > apply_mask_ipv6 (p); > > + int id; > + id = get_vrfid_by_tableno(AFI_IP6, safi, vrf_id); > /* Lookup table. */ > - table = vrf_table (AFI_IP6, safi, 0); > + table = vrf_table (AFI_IP6, safi, id); > if (! table) > return 0; > > @@ -3163,17 +3271,21 @@ rib_update (void) > struct route_node *rn; > struct route_table *table; > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (table) > for (rn = route_top (table); rn; rn = route_next (rn)) > if (rnode_to_ribs (rn)) > rib_queue_add (&zebrad, rn); > + } > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (table) > for (rn = route_top (table); rn; rn = route_next (rn)) > if (rnode_to_ribs (rn)) > rib_queue_add (&zebrad, rn); > + } > } > > > @@ -3193,8 +3305,9 @@ rib_weed_table (struct route_table *table) > continue; > > if (rib->table != zebrad.rtm_table_default && > - rib->table != RT_TABLE_MAIN) > - rib_delnode (rn, rib); > + rib->table != RT_TABLE_MAIN && > + rib->table != 0) > + rib_delnode (rn, rib); > } > } > > @@ -3298,8 +3411,11 @@ rib_close_table (struct route_table *table) > void > rib_close (void) > { > - rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0)); > - rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0)); > + for (int i = 0; i < vector_count(vrf_vector); i++) > + { > + rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, i)); > + rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, i)); > + } > } > > /* Routing information base initialize. */ > diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c > index baa60db..df3b353 100644 > --- a/zebra/zebra_vty.c > +++ b/zebra/zebra_vty.c > @@ -777,6 +777,7 @@ vty_show_ip_route (struct vty *vty, struct route_node > *rn, struct rib *rib) > tm->tm_yday/7, > tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); > } > + //vty_out (vty, ", tableno %d", rib->table); > Dead code, please remove.. > vty_out (vty, "%s", VTY_NEWLINE); > } > } > @@ -793,9 +794,10 @@ DEFUN (show_ip_route, > struct rib *rib; > int first = 1; > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show all IPv4 routes. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -808,6 +810,7 @@ DEFUN (show_ip_route, > } > vty_show_ip_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -834,9 +837,10 @@ DEFUN (show_ip_route_prefix_longer, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show matched type IPv4 routes. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -850,6 +854,7 @@ DEFUN (show_ip_route_prefix_longer, > } > vty_show_ip_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -867,9 +872,10 @@ DEFUN (show_ip_route_supernets, > u_int32_t addr; > int first = 1; > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show matched type IPv4 routes. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -889,6 +895,7 @@ DEFUN (show_ip_route_supernets, > vty_show_ip_route (vty, rn, rib); > } > } > + } > return CMD_SUCCESS; > } > > @@ -913,9 +920,10 @@ DEFUN (show_ip_route_protocol, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show matched type IPv4 routes. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -929,6 +937,7 @@ DEFUN (show_ip_route_protocol, > } > vty_show_ip_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -952,9 +961,10 @@ DEFUN (show_ip_route_addr, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > rn = route_node_match (table, (struct prefix *) &p); > if (! rn) > @@ -967,6 +977,7 @@ DEFUN (show_ip_route_addr, > > route_unlock_node (rn); > > + } > return CMD_SUCCESS; > } > > @@ -990,9 +1001,10 @@ DEFUN (show_ip_route_prefix, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > rn = route_node_match (table, (struct prefix *) &p); > if (! rn || rn->p.prefixlen != p.prefixlen) > @@ -1005,6 +1017,7 @@ DEFUN (show_ip_route_prefix, > > route_unlock_node (rn); > > + } > return CMD_SUCCESS; > } > > @@ -1083,12 +1096,14 @@ DEFUN (show_ip_route_summary, > { > struct route_table *table; > > - table = vrf_table (AFI_IP, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > vty_show_ip_route_summary (vty, table); > > + } > return CMD_SUCCESS; > } > > @@ -1192,9 +1207,10 @@ DEFUN (show_ip_mroute, > struct rib *rib; > int first = 1; > > - table = vrf_table (AFI_IP, SAFI_MULTICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP, SAFI_MULTICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show all IPv4 routes. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -1207,6 +1223,7 @@ DEFUN (show_ip_mroute, > } > vty_show_ip_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -1731,9 +1748,10 @@ DEFUN (show_ipv6_route, > struct rib *rib; > int first = 1; > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show all IPv6 route. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -1746,6 +1764,7 @@ DEFUN (show_ipv6_route, > } > vty_show_ipv6_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -1765,9 +1784,10 @@ DEFUN (show_ipv6_route_prefix_longer, > int ret; > int first = 1; > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > ret = str2prefix (argv[0], &p); > if (! ret) > @@ -1788,6 +1808,7 @@ DEFUN (show_ipv6_route_prefix_longer, > } > vty_show_ipv6_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -1812,9 +1833,10 @@ DEFUN (show_ipv6_route_protocol, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show matched type IPv6 routes. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -1828,6 +1850,7 @@ DEFUN (show_ipv6_route_protocol, > } > vty_show_ipv6_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > @@ -1851,20 +1874,22 @@ DEFUN (show_ipv6_route_addr, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > rn = route_node_match (table, (struct prefix *) &p); > if (! rn) > { > vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); > - return CMD_WARNING; > + continue; > } > > vty_show_ipv6_route_detail (vty, rn); > > route_unlock_node (rn); > + } > > return CMD_SUCCESS; > } > @@ -1889,21 +1914,22 @@ DEFUN (show_ipv6_route_prefix, > return CMD_WARNING; > } > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > rn = route_node_match (table, (struct prefix *) &p); > if (! rn || rn->p.prefixlen != p.prefixlen) > { > vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); > - return CMD_WARNING; > + continue; > } > > vty_show_ipv6_route_detail (vty, rn); > > route_unlock_node (rn); > - > + } > return CMD_SUCCESS; > } > > @@ -1918,12 +1944,14 @@ DEFUN (show_ipv6_route_summary, > { > struct route_table *table; > > - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > vty_show_ip_route_summary (vty, table); > > + } > return CMD_SUCCESS; > } > > @@ -1944,9 +1972,10 @@ DEFUN (show_ipv6_mroute, > struct rib *rib; > int first = 1; > > - table = vrf_table (AFI_IP6, SAFI_MULTICAST, 0); > + VRF_FOREACH_TABLE(AFI_IP6, SAFI_MULTICAST, table) > + { > if (! table) > - return CMD_SUCCESS; > + continue; > > /* Show all IPv6 route. */ > for (rn = route_top (table); rn; rn = route_next (rn)) > @@ -1959,6 +1988,7 @@ DEFUN (show_ipv6_mroute, > } > vty_show_ipv6_route (vty, rn, rib); > } > + } > return CMD_SUCCESS; > } > > diff --git a/zebra/zserv.c b/zebra/zserv.c > index ca17c2c..97048b1 100644 > --- a/zebra/zserv.c > +++ b/zebra/zserv.c > @@ -1577,7 +1577,12 @@ DEFUN (config_table, > "Configure target kernel routing table\n" > "TABLE integer\n") > { > - zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10); > + int tableno; > + tableno = strtol (argv[0], (char**)0, 10); > + zebrad.rtm_table_default = tableno; > + if (!vrf_tableno_exists(tableno)){ > + vrf_create(tableno); > + } > return CMD_SUCCESS; > } > > > > 2015-12-31 17:56 GMT+08:00 林守磊 <linxiu...@gmail.com>: > >> Hi All >> I use zebra in my production environment, but found that command table >> was not good as I thounght..And I found someone got the same problem just >> like me. http://www.gossamer-threads.com/lists/quagga/users/23301 >> >> At last, I had to fix problems in below by myself >> >> 1. At first, it can not inject a route to non-default route table which >> is already in default route >> >> 2. It can not define multiple route tables >> >> The patch(perfect_cmd_table.patch) is tested. >> >> Example zebra.conf like >> >> table 100 >> ip route 11.0.0.0/8 10.97.215.247 >> ip route 172.16.0.0/12 10.97.215.247 >> ! >> table 101 >> ip route 11.0.0.0/8 10.97.215.247 >> ip route 172.16.0.0/12 10.97.215.247 >> ip route 10.0.0.0/8 10.97.215.247 >> ip route 100.64.0.0/10 10.97.215.247 >> ! >> >> Forwarding Your Reply. >> >> Regards >> > > > _______________________________________________ > Quagga-dev mailing list > Quagga-dev@lists.quagga.net > https://lists.quagga.net/mailman/listinfo/quagga-dev >
_______________________________________________ Quagga-dev mailing list Quagga-dev@lists.quagga.net https://lists.quagga.net/mailman/listinfo/quagga-dev