if (!bgp)
return CMD_WARNING;
+ if (bgp->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
evpn_set_advertise_default_gw(bgp, NULL);
return CMD_SUCCESS;
if (!bgp)
return CMD_WARNING;
+ if (bgp->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
evpn_unset_advertise_default_gw(bgp, NULL);
return CMD_SUCCESS;
if (!bgp_vrf)
return CMD_WARNING;
+ if (bgp_vrf->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
bgp_vrf->evpn_info->dup_addr_detect = true;
if (time_val)
if (!bgp_vrf)
return CMD_WARNING;
+ if (bgp_vrf->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
bgp_vrf->evpn_info->dup_addr_detect = true;
bgp_vrf->evpn_info->dad_freeze = true;
bgp_vrf->evpn_info->dad_freeze_time = freeze_time;
if (!bgp_vrf)
return CMD_WARNING;
+ if (bgp_vrf->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
if (argc == 2) {
if (!bgp_vrf->evpn_info->dup_addr_detect)
return CMD_SUCCESS;
vrf_id_t vrf_id,
vrf_id_t *new_vrf_id)
{
- unsigned int ifindex;
+ char ifname[INTERFACE_NAMSIZ];
struct interface *ifp;
vrf_id_t new_id;
- /* Get interface index. */
- ifindex = stream_getl(s);
+ /* Read interface name. */
+ stream_get(ifname, s, INTERFACE_NAMSIZ);
/* Lookup interface. */
- ifp = if_lookup_by_index(ifindex, vrf_id);
+ ifp = if_lookup_by_name(ifname, vrf_id);
if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
- "INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
- ifindex, vrf_id);
+ "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
+ ifname, vrf_id);
return NULL;
}
#include "distribute.h"
#include "libfrr.h"
#include "routemap.h"
+#include "nexthop_group.h"
#include "sharp_zebra.h"
#include "sharp_vty.h"
master = frr_init();
+ nexthop_group_init(NULL, NULL, NULL, NULL);
vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init();
#include "log.h"
#include "vrf.h"
#include "zclient.h"
+#include "nexthop_group.h"
#include "sharpd/sharp_zebra.h"
#include "sharpd/sharp_vty.h"
DEFPY (install_routes,
install_routes_cmd,
- "sharp install routes A.B.C.D$start nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6> (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]",
"Sharp routing Protocol\n"
"install some routes\n"
"Routes to install\n"
"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")
int i;
struct prefix p;
struct nexthop nhop;
+ struct nexthop_group nhg;
uint32_t temp;
total_routes = 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;
+ 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 {
- memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN);
- nhop.type = NEXTHOP_TYPE_IPV6;
+ 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);
}
#include "plist.h"
#include "log.h"
#include "nexthop.h"
+#include "nexthop_group.h"
#include "sharp_zebra.h"
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;
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);
}
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
$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/) {
"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")
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")
if (h->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- zlog_err("%s error: message truncated",
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "%s error: message truncated",
nl->name);
return -1;
}
continue;
}
- if (h->nlmsg_len
- < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
- "%s error: message truncated",
- nl->name);
- return -1;
- }
-
/* Deal with errors that occur because of races
* in link handling */
if (zns->is_cmd
zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
- /* Fill in the ifIndex of the interface and its new VRF (id) */
- stream_putl(s, ifp->ifindex);
+ /* Fill in the name of the interface and its new VRF (id) */
+ stream_put(s, ifp->name, INTERFACE_NAMSIZ);
stream_putl(s, vrf_id);
/* Write packet size. */