mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 16:04:49 +00:00
Merge pull request #3562 from donaldsharp/sharp_multiple_installs
Sharp multiple installs
This commit is contained in:
commit
f9ad1afefe
@ -33,16 +33,20 @@ All sharp commands are under the enable node and preceeded by the ``sharp``
|
|||||||
keyword. At present, no sharp commands will be preserved in the config.
|
keyword. At present, no sharp commands will be preserved in the config.
|
||||||
|
|
||||||
.. index:: sharp install
|
.. index:: sharp install
|
||||||
.. clicmd:: sharp install routes A.B.C.D nexthop <E.F.G.H|X:X::X:X> (1-1000000)
|
.. clicmd:: sharp install routes A.B.C.D <nexthop <E.F.G.H|X:X::X:X>|nexthop-group NAME> (1-1000000) [instance (0-255)] [repeat (2-1000)]
|
||||||
|
|
||||||
Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D``
|
Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D``
|
||||||
with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is
|
with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is
|
||||||
a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable
|
a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable
|
||||||
to be installed into the kernel. The routes are installed into zebra as
|
to be installed into the kernel. Alternatively a nexthop-group NAME
|
||||||
``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route
|
can be specified and used as the nexthops. The routes are installed into
|
||||||
|
zebra as ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route
|
||||||
redistribution. Route installation time is noted in the debug
|
redistribution. Route installation time is noted in the debug
|
||||||
log. When zebra successfully installs a route into the kernel and SHARP
|
log. When zebra successfully installs a route into the kernel and SHARP
|
||||||
receives success notifications for all routes this is logged as well.
|
receives success notifications for all routes this is logged as well.
|
||||||
|
Instance (0-255) if specified causes the routes to be installed in a different
|
||||||
|
instance. If repeat is used then we will install/uninstall the routes the
|
||||||
|
number of times specified.
|
||||||
|
|
||||||
.. index:: sharp remove
|
.. index:: sharp remove
|
||||||
.. clicmd:: sharp remove routes A.B.C.D (1-1000000)
|
.. clicmd:: sharp remove routes A.B.C.D (1-1000000)
|
||||||
|
@ -40,6 +40,14 @@ extern uint32_t total_routes;
|
|||||||
extern uint32_t installed_routes;
|
extern uint32_t installed_routes;
|
||||||
extern uint32_t removed_routes;
|
extern uint32_t removed_routes;
|
||||||
|
|
||||||
|
uint8_t inst;
|
||||||
|
struct prefix prefix;
|
||||||
|
struct prefix orig_prefix;
|
||||||
|
struct nexthop nhop;
|
||||||
|
struct nexthop_group nhop_group;
|
||||||
|
uint32_t rts;
|
||||||
|
int32_t repeat;
|
||||||
|
|
||||||
DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
|
DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
|
||||||
"sharp watch nexthop X:X::X:X$nhop",
|
"sharp watch nexthop X:X::X:X$nhop",
|
||||||
"Sharp routing Protocol\n"
|
"Sharp routing Protocol\n"
|
||||||
@ -82,7 +90,7 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
|
|||||||
|
|
||||||
DEFPY (install_routes,
|
DEFPY (install_routes,
|
||||||
install_routes_cmd,
|
install_routes_cmd,
|
||||||
"sharp install routes A.B.C.D$start <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance]",
|
"sharp install routes A.B.C.D$start <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
|
||||||
"Sharp routing Protocol\n"
|
"Sharp routing Protocol\n"
|
||||||
"install some routes\n"
|
"install some routes\n"
|
||||||
"Routes to install\n"
|
"Routes to install\n"
|
||||||
@ -94,24 +102,27 @@ DEFPY (install_routes,
|
|||||||
"The Name of the nexthop-group\n"
|
"The Name of the nexthop-group\n"
|
||||||
"How many to create\n"
|
"How many to create\n"
|
||||||
"Instance to use\n"
|
"Instance to use\n"
|
||||||
"Instance\n")
|
"Instance\n"
|
||||||
|
"Should we repeat this command\n"
|
||||||
|
"How many times to repeat this command\n")
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct prefix p;
|
|
||||||
struct nexthop nhop;
|
|
||||||
struct nexthop_group nhg;
|
|
||||||
uint32_t temp;
|
|
||||||
|
|
||||||
total_routes = routes;
|
total_routes = routes;
|
||||||
installed_routes = 0;
|
installed_routes = 0;
|
||||||
|
|
||||||
memset(&p, 0, sizeof(p));
|
if (rpt >= 2)
|
||||||
memset(&nhop, 0, sizeof(nhop));
|
repeat = rpt * 2;
|
||||||
memset(&nhg, 0, sizeof(nhg));
|
else
|
||||||
|
repeat = 0;
|
||||||
|
|
||||||
p.family = AF_INET;
|
memset(&prefix, 0, sizeof(prefix));
|
||||||
p.prefixlen = 32;
|
memset(&orig_prefix, 0, sizeof(orig_prefix));
|
||||||
p.u.prefix4 = start;
|
memset(&nhop, 0, sizeof(nhop));
|
||||||
|
memset(&nhop_group, 0, sizeof(nhop_group));
|
||||||
|
|
||||||
|
prefix.family = AF_INET;
|
||||||
|
prefix.prefixlen = 32;
|
||||||
|
prefix.u.prefix4 = start;
|
||||||
|
orig_prefix = prefix;
|
||||||
|
|
||||||
if (nexthop_group) {
|
if (nexthop_group) {
|
||||||
struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
|
struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
|
||||||
@ -122,7 +133,7 @@ DEFPY (install_routes,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
nhg.nexthop = nhgc->nhg.nexthop;
|
nhop_group.nexthop = nhgc->nhg.nexthop;
|
||||||
} else {
|
} else {
|
||||||
if (nexthop4.s_addr != INADDR_ANY) {
|
if (nexthop4.s_addr != INADDR_ANY) {
|
||||||
nhop.gate.ipv4 = nexthop4;
|
nhop.gate.ipv4 = nexthop4;
|
||||||
@ -132,15 +143,12 @@ DEFPY (install_routes,
|
|||||||
nhop.type = NEXTHOP_TYPE_IPV6;
|
nhop.type = NEXTHOP_TYPE_IPV6;
|
||||||
}
|
}
|
||||||
|
|
||||||
nhg.nexthop = &nhop;
|
nhop_group.nexthop = &nhop;
|
||||||
}
|
}
|
||||||
zlog_debug("Inserting %ld routes", routes);
|
|
||||||
|
|
||||||
temp = ntohl(p.u.prefix4.s_addr);
|
inst = instance;
|
||||||
for (i = 0; i < routes; i++) {
|
rts = routes;
|
||||||
route_add(&p, (uint8_t)instance, &nhg);
|
sharp_install_routes_helper(&prefix, inst, &nhop_group, rts);
|
||||||
p.u.prefix4.s_addr = htonl(++temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -186,25 +194,18 @@ DEFPY (remove_routes,
|
|||||||
"instance to use\n"
|
"instance to use\n"
|
||||||
"Value of instance\n")
|
"Value of instance\n")
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct prefix p;
|
|
||||||
uint32_t temp;
|
|
||||||
total_routes = routes;
|
total_routes = routes;
|
||||||
removed_routes = 0;
|
removed_routes = 0;
|
||||||
|
|
||||||
memset(&p, 0, sizeof(p));
|
memset(&prefix, 0, sizeof(prefix));
|
||||||
|
|
||||||
p.family = AF_INET;
|
prefix.family = AF_INET;
|
||||||
p.prefixlen = 32;
|
prefix.prefixlen = 32;
|
||||||
p.u.prefix4 = start;
|
prefix.u.prefix4 = start;
|
||||||
|
|
||||||
zlog_debug("Removing %ld routes", routes);
|
inst = instance;
|
||||||
|
rts = routes;
|
||||||
temp = ntohl(p.u.prefix4.s_addr);
|
sharp_remove_routes_helper(&prefix, inst, rts);
|
||||||
for (i = 0; i < routes; i++) {
|
|
||||||
route_delete(&p, (uint8_t)instance);
|
|
||||||
p.u.prefix4.s_addr = htonl(++temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,59 @@ static int interface_state_down(int command, struct zclient *zclient,
|
|||||||
extern uint32_t total_routes;
|
extern uint32_t total_routes;
|
||||||
extern uint32_t installed_routes;
|
extern uint32_t installed_routes;
|
||||||
extern uint32_t removed_routes;
|
extern uint32_t removed_routes;
|
||||||
|
extern int32_t repeat;
|
||||||
|
extern struct prefix orig_prefix;
|
||||||
|
extern struct nexthop_group nhop_group;
|
||||||
|
extern uint8_t inst;
|
||||||
|
|
||||||
|
void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
|
||||||
|
struct nexthop_group *nhg,
|
||||||
|
uint32_t routes)
|
||||||
|
{
|
||||||
|
uint32_t temp, i;
|
||||||
|
|
||||||
|
zlog_debug("Inserting %u routes", routes);
|
||||||
|
|
||||||
|
temp = ntohl(p->u.prefix4.s_addr);
|
||||||
|
for (i = 0; i < routes; i++) {
|
||||||
|
route_add(p, (uint8_t)instance, nhg);
|
||||||
|
p->u.prefix4.s_addr = htonl(++temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
|
||||||
|
uint32_t routes)
|
||||||
|
{
|
||||||
|
uint32_t temp, i;
|
||||||
|
|
||||||
|
zlog_debug("Removing %u routes", routes);
|
||||||
|
|
||||||
|
temp = ntohl(p->u.prefix4.s_addr);
|
||||||
|
for (i = 0; i < routes; i++) {
|
||||||
|
route_delete(p, (uint8_t)instance);
|
||||||
|
p->u.prefix4.s_addr = htonl(++temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_repeated(bool installed)
|
||||||
|
{
|
||||||
|
struct prefix p = orig_prefix;
|
||||||
|
repeat--;
|
||||||
|
|
||||||
|
if (repeat <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (installed) {
|
||||||
|
removed_routes = 0;
|
||||||
|
sharp_remove_routes_helper(&p, inst, total_routes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!installed) {
|
||||||
|
installed_routes = 0;
|
||||||
|
sharp_install_routes_helper(&p, inst, &nhop_group,
|
||||||
|
total_routes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int route_notify_owner(int command, struct zclient *zclient,
|
static int route_notify_owner(int command, struct zclient *zclient,
|
||||||
zebra_size_t length, vrf_id_t vrf_id)
|
zebra_size_t length, vrf_id_t vrf_id)
|
||||||
@ -146,8 +199,10 @@ static int route_notify_owner(int command, struct zclient *zclient,
|
|||||||
switch (note) {
|
switch (note) {
|
||||||
case ZAPI_ROUTE_INSTALLED:
|
case ZAPI_ROUTE_INSTALLED:
|
||||||
installed_routes++;
|
installed_routes++;
|
||||||
if (total_routes == installed_routes)
|
if (total_routes == installed_routes) {
|
||||||
zlog_debug("Installed All Items");
|
zlog_debug("Installed All Items");
|
||||||
|
handle_repeated(true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_FAIL_INSTALL:
|
case ZAPI_ROUTE_FAIL_INSTALL:
|
||||||
zlog_debug("Failed install of route");
|
zlog_debug("Failed install of route");
|
||||||
@ -157,8 +212,10 @@ static int route_notify_owner(int command, struct zclient *zclient,
|
|||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_REMOVED:
|
case ZAPI_ROUTE_REMOVED:
|
||||||
removed_routes++;
|
removed_routes++;
|
||||||
if (total_routes == removed_routes)
|
if (total_routes == removed_routes) {
|
||||||
zlog_debug("Removed all Items");
|
zlog_debug("Removed all Items");
|
||||||
|
handle_repeated(false);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ZAPI_ROUTE_REMOVE_FAIL:
|
case ZAPI_ROUTE_REMOVE_FAIL:
|
||||||
zlog_debug("Route removal Failure");
|
zlog_debug("Route removal Failure");
|
||||||
|
@ -29,4 +29,10 @@ extern void route_add(struct prefix *p, uint8_t instance,
|
|||||||
struct nexthop_group *nhg);
|
struct nexthop_group *nhg);
|
||||||
extern void route_delete(struct prefix *p, uint8_t instance);
|
extern void route_delete(struct prefix *p, uint8_t instance);
|
||||||
extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch);
|
extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch);
|
||||||
|
|
||||||
|
extern void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
|
||||||
|
struct nexthop_group *nhg,
|
||||||
|
uint32_t routes);
|
||||||
|
extern void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
|
||||||
|
uint32_t routes);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user