#include "nexthop.h"
#include "nexthop_group.h"
#include "log.h"
-#include "json.h"
#include "debug.h"
+#include "pbr.h"
#include "pbrd/pbr_nht.h"
#include "pbrd/pbr_map.h"
#include "pbrd/pbr_vty_clippy.c"
#endif
-DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map WORD seq (1-1000)",
+DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map WORD seq (1-700)",
"Create pbr-map or enter pbr-map command mode\n"
"The name of the PBR MAP\n"
"Sequence to insert in existing pbr-map entry\n"
return CMD_SUCCESS;
}
-DEFUN_NOSH(no_pbr_map, no_pbr_map_cmd, "no pbr-map WORD [seq (1-65535)]",
+DEFUN_NOSH(no_pbr_map, no_pbr_map_cmd, "no pbr-map WORD [seq (1-700)]",
NO_STR
"Delete pbr-map\n"
"The name of the PBR MAP\n"
return CMD_SUCCESS;
}
+DEFPY(pbr_set_table_range,
+ pbr_set_table_range_cmd,
+ "[no] pbr table range (10000-4294966272)$lb (10000-4294966272)$ub",
+ NO_STR
+ PBR_STR
+ "Set table ID range\n"
+ "Set table ID range\n"
+ "Lower bound for table ID range\n"
+ "Upper bound for table ID range\n")
+{
+ /* upper bound is 2^32 - 2^10 */
+ int ret = CMD_WARNING;
+ const int minrange = 1000;
+
+ /* validate given bounds */
+ if (lb > ub)
+ vty_out(vty, "%% Lower bound must be less than upper bound\n");
+ else if (ub - lb < minrange)
+ vty_out(vty, "%% Range breadth must be at least %d\n", minrange);
+ else {
+ ret = CMD_SUCCESS;
+ pbr_nht_set_tableid_range((uint32_t) lb, (uint32_t) ub);
+ }
+
+ return ret;
+}
+
+
DEFPY(pbr_map_match_src, pbr_map_match_src_cmd,
"[no] match src-ip <A.B.C.D/M|X:X::X:X/M>$prefix",
NO_STR
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ pbrms->family = prefix->family;
+
if (!no) {
if (prefix_same(pbrms->src, prefix))
return CMD_SUCCESS;
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ pbrms->family = prefix->family;
+
if (!no) {
if (prefix_same(pbrms->dst, prefix))
return CMD_SUCCESS;
memset(&nhop, 0, sizeof(nhop));
nhop.vrf_id = vrf->vrf_id;
+ /*
+ * Make SA happy. CLIPPY is not going to give us a NULL
+ * addr.
+ */
+ assert(addr);
if (addr->sa.sa_family == AF_INET) {
nhop.gate.ipv4.s_addr = addr->sin.sin_addr.s_addr;
if (intf) {
intf, vrf->name);
return CMD_WARNING_CONFIG_FAILED;
}
- } else
+ } else {
+ if (IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) {
+ vty_out(vty,
+ "Specified a v6 LL with no interface, rejecting\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
nhop.type = NEXTHOP_TYPE_IPV6;
+ }
}
if (pbrms->nhg)
nh = nexthop_exists(pbrms->nhg, &nhop);
else {
- char buf[100];
+ char buf[PBR_NHC_NAMELEN];
if (no) {
vty_out(vty, "No nexthops to delete");
pbrms->internal_nhg_name =
XSTRDUP(MTYPE_TMP,
pbr_nht_nexthop_make_name(pbrms->parent->name,
- PBR_MAP_NAMELEN,
+ PBR_NHC_NAMELEN,
pbrms->seqno,
buf));
nh = NULL;
pbrm = pbrm_find(mapname);
if (!pbr_ifp) {
- /*
- * Some one could have fat fingered the interface
- * name
- */
+ /* we don't want one and we don't have one, so... */
+ if (no)
+ return CMD_SUCCESS;
+
+ /* Some one could have fat fingered the interface name */
pbr_ifp = pbr_if_new(ifp);
}
if (no) {
if (strcmp(pbr_ifp->mapname, mapname) == 0) {
- strcpy(pbr_ifp->mapname, "");
-
+ pbr_ifp->mapname[0] = '\0';
if (pbrm)
pbr_map_interface_delete(pbrm, ifp);
}
} else {
- if (strcmp(pbr_ifp->mapname, "") == 0) {
- strcpy(pbr_ifp->mapname, mapname);
-
- if (pbrm)
- pbr_map_add_interface(pbrm, ifp);
- } else {
- if (!(strcmp(pbr_ifp->mapname, mapname) == 0)) {
- old_pbrm = pbrm_find(pbr_ifp->mapname);
- if (old_pbrm)
- pbr_map_interface_delete(old_pbrm, ifp);
- strcpy(pbr_ifp->mapname, mapname);
- if (pbrm)
- pbr_map_add_interface(pbrm, ifp);
- }
+ if (strcmp(pbr_ifp->mapname, "") != 0) {
+ old_pbrm = pbrm_find(pbr_ifp->mapname);
+ if (old_pbrm)
+ pbr_map_interface_delete(old_pbrm, ifp);
}
+ snprintf(pbr_ifp->mapname, sizeof(pbr_ifp->mapname),
+ "%s", mapname);
+ if (pbrm)
+ pbr_map_add_interface(pbrm, ifp);
}
return CMD_SUCCESS;
DEFPY (show_pbr,
show_pbr_cmd,
- "show pbr [json$json]",
+ "show pbr",
SHOW_STR
- "Policy Based Routing\n"
- JSON_STR)
+ PBR_STR)
{
pbr_nht_write_table_range(vty);
pbr_nht_write_rule_range(vty);
DEFPY (show_pbr_map,
show_pbr_map_cmd,
- "show pbr map [NAME$name] [detail$detail] [json$json]",
+ "show pbr map [NAME$name] [detail$detail]",
SHOW_STR
- "Policy Based Routing\n"
+ PBR_STR
"PBR Map\n"
"PBR Map Name\n"
- "Detailed information\n"
- JSON_STR)
+ "Detailed information\n")
{
struct pbr_map_sequence *pbrms;
struct pbr_map *pbrm;
pbr_map_reason_string(pbrms->reason, rbuf,
sizeof(rbuf));
vty_out(vty,
- " Seq: %u rule: %u Installed: %d(%u) Reason: %s\n",
+ " Seq: %u rule: %u Installed: %" PRIu64 "(%u) Reason: %s\n",
pbrms->seqno, pbrms->ruleno, pbrms->installed,
pbrms->unique, pbrms->reason ? rbuf : "Valid");
show_pbr_nexthop_group_cmd,
"show pbr nexthop-groups [WORD$word]",
SHOW_STR
- "Policy Based Routing\n"
+ PBR_STR
"Nexthop Groups\n"
"Optional Name of the nexthop group\n")
{
DEFPY (show_pbr_interface,
show_pbr_interface_cmd,
- "show pbr interface [NAME$name] [json$json]",
+ "show pbr interface [NAME$name]",
SHOW_STR
- "Policy Based Routing\n"
+ PBR_STR
"PBR Interface\n"
- "PBR Interface Name\n"
- JSON_STR)
+ "PBR Interface Name\n")
{
struct interface *ifp;
struct vrf *vrf;
return CMD_SUCCESS;
}
+/* PBR debugging CLI ------------------------------------------------------- */
+
+static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
+
+DEFPY(debug_pbr,
+ debug_pbr_cmd,
+ "[no] debug pbr [{map$map|zebra$zebra|nht$nht|events$events}]",
+ NO_STR
+ DEBUG_STR
+ PBR_STR
+ "Policy maps\n"
+ "PBRD <-> Zebra communications\n"
+ "Nexthop tracking\n"
+ "Events\n")
+{
+ uint32_t mode = DEBUG_NODE2MODE(vty->node);
+
+ if (map)
+ DEBUG_MODE_SET(&pbr_dbg_map, mode, !no);
+ if (zebra)
+ DEBUG_MODE_SET(&pbr_dbg_zebra, mode, !no);
+ if (nht)
+ DEBUG_MODE_SET(&pbr_dbg_nht, mode, !no);
+ if (events)
+ DEBUG_MODE_SET(&pbr_dbg_event, mode, !no);
+
+ /* no specific debug --> act on all of them */
+ if (strmatch(argv[argc - 1]->text, "pbr"))
+ pbr_debug_set_all(mode, !no);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_NOSH(show_debugging_pbr,
+ show_debugging_pbr_cmd,
+ "show debugging [pbr]",
+ SHOW_STR
+ DEBUG_STR
+ PBR_STR)
+{
+ vty_out(vty, "PBR debugging status:\n");
+
+ pbr_debug_config_write_helper(vty, false);
+
+ return CMD_SUCCESS;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
static struct cmd_node interface_node = {
INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
};
vty_frame(vty, "interface %s vrf %s\n",
ifp->name, vrf->name);
+ if (ifp->desc)
+ vty_out(vty, " description %s\n", ifp->desc);
+
pbr_map_write_interfaces(vty, ifp);
vty_endframe(vty, "!\n");
install_node(&pbr_map_node,
pbr_vty_map_config_write);
+ /* debug */
+ install_node(&debug_node, pbr_debug_config_write);
+ install_element(VIEW_NODE, &debug_pbr_cmd);
+ install_element(CONFIG_NODE, &debug_pbr_cmd);
+ install_element(VIEW_NODE, &show_debugging_pbr_cmd);
+
install_default(PBRMAP_NODE);
install_element(CONFIG_NODE, &pbr_map_cmd);
install_element(CONFIG_NODE, &no_pbr_map_cmd);
+ install_element(CONFIG_NODE, &pbr_set_table_range_cmd);
install_element(INTERFACE_NODE, &pbr_policy_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_src_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_dst_cmd);
install_element(VIEW_NODE, &show_pbr_map_cmd);
install_element(VIEW_NODE, &show_pbr_interface_cmd);
install_element(VIEW_NODE, &show_pbr_nexthop_group_cmd);
-
- pbr_debug_init_vty();
}