diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c index 20cdd21e7d..175a276089 100644 --- a/sharpd/sharp_main.c +++ b/sharpd/sharp_main.c @@ -42,6 +42,7 @@ #include "distribute.h" #include "libfrr.h" #include "routemap.h" +#include "nexthop_group.h" #include "sharp_zebra.h" #include "sharp_vty.h" @@ -150,6 +151,7 @@ int main(int argc, char **argv, char **envp) master = frr_init(); + nexthop_group_init(NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL); access_list_init(); diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 797e336c2d..3aed8eb123 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -28,6 +28,7 @@ #include "log.h" #include "vrf.h" #include "zclient.h" +#include "nexthop_group.h" #include "sharpd/sharp_zebra.h" #include "sharpd/sharp_vty.h" @@ -81,7 +82,7 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, DEFPY (install_routes, install_routes_cmd, - "sharp install routes A.B.C.D$start nexthop (1-1000000)$routes [instance (0-255)$instance]", + "sharp install routes A.B.C.D$start |nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance]", "Sharp routing Protocol\n" "install some routes\n" "Routes to install\n" @@ -89,6 +90,8 @@ DEFPY (install_routes, "Nexthop to use(Can be an IPv4 or IPv6 address)\n" "V4 Nexthop address to use\n" "V6 Nexthop address to use\n" + "Nexthop-Group to use\n" + "The Name of the nexthop-group\n" "How many to create\n" "Instance to use\n" "Instance\n") @@ -96,6 +99,7 @@ DEFPY (install_routes, int i; struct prefix p; struct nexthop nhop; + struct nexthop_group nhg; uint32_t temp; total_routes = routes; @@ -103,24 +107,38 @@ DEFPY (install_routes, memset(&p, 0, sizeof(p)); memset(&nhop, 0, sizeof(nhop)); + memset(&nhg, 0, sizeof(nhg)); p.family = AF_INET; p.prefixlen = 32; p.u.prefix4 = start; - if (nexthop4.s_addr != INADDR_ANY) { - nhop.gate.ipv4 = nexthop4; - nhop.type = NEXTHOP_TYPE_IPV4; - } else { - memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN); - nhop.type = NEXTHOP_TYPE_IPV6; - } + if (nexthop_group) { + struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group); + if (!nhgc) { + vty_out(vty, + "Specified Nexthop Group: %s does not exist\n", + nexthop_group); + return CMD_WARNING; + } + nhg.nexthop = nhgc->nhg.nexthop; + } else { + if (nexthop4.s_addr != INADDR_ANY) { + nhop.gate.ipv4 = nexthop4; + nhop.type = NEXTHOP_TYPE_IPV4; + } else { + nhop.gate.ipv6 = nexthop6; + nhop.type = NEXTHOP_TYPE_IPV6; + } + + nhg.nexthop = &nhop; + } zlog_debug("Inserting %ld routes", routes); temp = ntohl(p.u.prefix4.s_addr); for (i = 0; i < routes; i++) { - route_add(&p, (uint8_t)instance, &nhop); + route_add(&p, (uint8_t)instance, &nhg); p.u.prefix4.s_addr = htonl(++temp); } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index f752009eb8..4a88b6c8ee 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -34,6 +34,7 @@ #include "plist.h" #include "log.h" #include "nexthop.h" +#include "nexthop_group.h" #include "sharp_zebra.h" @@ -176,10 +177,12 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label) zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); } -void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh) +void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg) { struct zapi_route api; struct zapi_nexthop *api_nh; + struct nexthop *nh; + int i = 0; memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; @@ -191,12 +194,35 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh) SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api_nh = &api.nexthops[0]; - api_nh->vrf_id = VRF_DEFAULT; - api_nh->gate = nh->gate; - api_nh->type = nh->type; - api_nh->ifindex = nh->ifindex; - api.nexthop_num = 1; + for (ALL_NEXTHOPS_PTR(nhg, nh)) { + api_nh = &api.nexthops[i]; + api_nh->vrf_id = VRF_DEFAULT; + api_nh->type = nh->type; + switch (nh->type) { + case NEXTHOP_TYPE_IPV4: + api_nh->gate = nh->gate; + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + api_nh->gate = nh->gate; + api_nh->ifindex = nh->ifindex; + break; + case NEXTHOP_TYPE_IFINDEX: + api_nh->ifindex = nh->ifindex; + break; + case NEXTHOP_TYPE_IPV6: + memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + api_nh->ifindex = nh->ifindex; + memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16); + break; + case NEXTHOP_TYPE_BLACKHOLE: + api_nh->bh_type = nh->bh_type; + break; + } + i++; + } + api.nexthop_num = i; zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 58438ed01d..ffe21df9b8 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -25,7 +25,8 @@ extern void sharp_zebra_init(void); extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label); -extern void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh); +extern void route_add(struct prefix *p, uint8_t instance, + struct nexthop_group *nhg); extern void route_delete(struct prefix *p, uint8_t instance); extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch); #endif diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 596f01738a..2b48f1f360 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -109,7 +109,7 @@ sub scan_file { $protocol = "VTYSH_ZEBRA"; } elsif ($file =~ /lib\/nexthop_group\.c$/) { - $protocol = "VTYSH_PBRD"; + $protocol = "VTYSH_PBRD | VTYSH_SHARPD"; } elsif ($file =~ /lib\/plist\.c$/) { if ($defun_array[1] =~ m/ipv6/) { diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 2327f2b46d..6cf45789dd 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2110,7 +2110,7 @@ DEFSH(VTYSH_ZEBRA, vtysh_no_logicalrouter_cmd, "The Name Space\n" "The file name in " NS_RUN_DIR ", or a full pathname\n") -DEFUNSH(VTYSH_PBRD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, +DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, "nexthop-group NAME", "Nexthop Group configuration\n" "Name of the Nexthop Group\n") @@ -2119,7 +2119,8 @@ DEFUNSH(VTYSH_PBRD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, return CMD_SUCCESS; } -DEFSH(VTYSH_PBRD, vtysh_no_nexthop_group_cmd, "no nexthop-group NAME", +DEFSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_no_nexthop_group_cmd, + "no nexthop-group NAME", NO_STR "Nexthop Group Configuration\n" "Name of the Nexthop Group\n")