pbrms->family = prefix->family;
if (!no) {
- if (prefix_same(pbrms->src, prefix))
- return CMD_SUCCESS;
+ if (pbrms->src) {
+ if (prefix_same(pbrms->src, prefix))
+ return CMD_SUCCESS;
- if (!pbrms->src)
- pbrms->src = prefix_new();
+ vty_out(vty,
+ "A `match src-ip XX` command already exists, please remove that first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ pbrms->src = prefix_new();
prefix_copy(pbrms->src, prefix);
- } else {
- prefix_free(pbrms->src);
- pbrms->src = 0;
- }
+ } else
+ prefix_free(&pbrms->src);
pbr_map_check(pbrms);
"[no] match dst-ip <A.B.C.D/M|X:X::X:X/M>$prefix",
NO_STR
"Match the rest of the command\n"
- "Choose the src ip or ipv6 prefix to use\n"
+ "Choose the dst ip or ipv6 prefix to use\n"
"v4 Prefix\n"
"v6 Prefix\n")
{
pbrms->family = prefix->family;
if (!no) {
- if (prefix_same(pbrms->dst, prefix))
- return CMD_SUCCESS;
+ if (pbrms->dst) {
+ if (prefix_same(pbrms->dst, prefix))
+ return CMD_SUCCESS;
+
+ vty_out(vty,
+ "A `match dst-ip XX` command already exists, please remove that first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (!pbrms->dst)
- pbrms->dst = prefix_new();
+ pbrms->dst = prefix_new();
prefix_copy(pbrms->dst, prefix);
- } else {
- prefix_free(pbrms->dst);
- pbrms->dst = NULL;
- }
+ } else
+ prefix_free(&pbrms->dst);
pbr_map_check(pbrms);
#endif
if (!no) {
- if (pbrms->mark == (uint32_t) mark)
- return CMD_SUCCESS;
- pbrms->mark = (uint32_t) mark;
- } else {
+ if (pbrms->mark) {
+ if (pbrms->mark == (uint32_t)mark)
+ return CMD_SUCCESS;
+
+ vty_out(vty,
+ "A `match mark XX` command already exists, please remove that first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ pbrms->mark = (uint32_t)mark;
+ } else
pbrms->mark = 0;
- }
pbr_map_check(pbrms);
return CMD_SUCCESS;
- }
+}
+
+#define SET_VRF_EXISTS_STR \
+ "A `set vrf XX` command already exists, please remove that first\n"
DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd,
- "[no] set nexthop-group NHGNAME$name",
- NO_STR
- "Set for the PBR-MAP\n"
- "nexthop-group to use\n"
- "The name of the nexthop-group\n")
+ "[no] set nexthop-group NHGNAME$name",
+ NO_STR
+ "Set for the PBR-MAP\n"
+ "nexthop-group to use\n"
+ "The name of the nexthop-group\n")
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
struct nexthop_group_cmd *nhgc;
return CMD_WARNING_CONFIG_FAILED;
}
+ if (pbrms->vrf_lookup || pbrms->vrf_unchanged) {
+ vty_out(vty, SET_VRF_EXISTS_STR);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
nhgc = nhgc_find(name);
if (!nhgc) {
vty_out(vty, "Specified nexthop-group %s does not exist\n",
name);
- vty_out(vty, "PBR-MAP will not be applied until it is created\n");
+ vty_out(vty,
+ "PBR-MAP will not be applied until it is created\n");
}
if (no) {
if (pbrms->nhgrp_name && strcmp(name, pbrms->nhgrp_name) == 0)
- pbr_map_delete_nexthop_group(pbrms);
+ pbr_map_delete_nexthops(pbrms);
else {
vty_out(vty,
- "Nexthop Group specified: %s does not exist to remove",
+ "Nexthop Group specified: %s does not exist to remove\n",
name);
return CMD_WARNING_CONFIG_FAILED;
}
if (pbrms->nhgrp_name) {
if (strcmp(name, pbrms->nhgrp_name) != 0) {
vty_out(vty,
- "Please delete current nexthop group before modifying current one");
+ "Please delete current nexthop group before modifying current one\n");
return CMD_WARNING_CONFIG_FAILED;
}
<A.B.C.D|X:X::X:X>$addr [INTERFACE$intf]\
|INTERFACE$intf\
>\
- [nexthop-vrf NAME$name]",
+ [nexthop-vrf NAME$vrf_name]",
NO_STR
"Set for the PBR-MAP\n"
"Specify one of the nexthops in this map\n"
if (pbrms->nhgrp_name) {
vty_out(vty,
- "Please unconfigure the nexthop group before adding an individual nexthop");
+ "Please unconfigure the nexthop group before adding an individual nexthop\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (pbrms->vrf_lookup || pbrms->vrf_unchanged) {
+ vty_out(vty, SET_VRF_EXISTS_STR);
return CMD_WARNING_CONFIG_FAILED;
}
- if (name)
- vrf = vrf_lookup_by_name(name);
+ if (vrf_name)
+ vrf = vrf_lookup_by_name(vrf_name);
else
vrf = vrf_lookup_by_id(VRF_DEFAULT);
if (!vrf) {
- vty_out(vty, "Specified: %s is non-existent\n", name);
+ vty_out(vty, "Specified: %s is non-existent\n", vrf_name);
return CMD_WARNING_CONFIG_FAILED;
}
if (pbrms->nhg->nexthop) {
vty_out(vty,
- "If you would like more than one nexthop please use nexthop-groups");
+ "If you would like more than one nexthop please use nexthop-groups\n");
return CMD_WARNING_CONFIG_FAILED;
}
pbr_map_check(pbrms);
}
- if (nhop.type == NEXTHOP_TYPE_IFINDEX) {
+ if (nhop.type == NEXTHOP_TYPE_IFINDEX
+ || (nhop.type == NEXTHOP_TYPE_IPV6_IFINDEX
+ && IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6))) {
struct interface *ifp;
ifp = if_lookup_by_index(nhop.ifindex, nhop.vrf_id);
return CMD_SUCCESS;
}
+DEFPY(pbr_map_vrf, pbr_map_vrf_cmd,
+ "[no] set vrf <NAME$vrf_name|unchanged>",
+ NO_STR
+ "Set for the PBR-MAP\n"
+ "Specify the VRF for this map\n"
+ "The VRF Name\n"
+ "Use the interface's VRF for lookup\n")
+{
+ struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ int ret = CMD_SUCCESS;
+
+ if (no) {
+ pbr_map_delete_vrf(pbrms);
+
+ /* Reset all data */
+ pbrms->nhs_installed = false;
+ pbrms->vrf_name[0] = '\0';
+ pbrms->vrf_lookup = false;
+ pbrms->vrf_unchanged = false;
+
+ goto done;
+ }
+
+ if (pbrms->nhgrp_name || pbrms->nhg) {
+ vty_out(vty,
+ "A `set nexthop/nexthop-group XX` command already exits, please remove that first\n");
+ ret = CMD_WARNING_CONFIG_FAILED;
+ goto done;
+ }
+
+ if (pbrms->vrf_lookup || pbrms->vrf_unchanged) {
+ vty_out(vty, SET_VRF_EXISTS_STR);
+ ret = CMD_WARNING_CONFIG_FAILED;
+ goto done;
+ }
+
+ if (vrf_name) {
+ if (!pbr_vrf_lookup_by_name(vrf_name)) {
+ vty_out(vty, "Specified: %s is non-existent\n",
+ vrf_name);
+ ret = CMD_WARNING_CONFIG_FAILED;
+ goto done;
+ }
+
+ pbrms->vrf_lookup = true;
+ strlcpy(pbrms->vrf_name, vrf_name, sizeof(pbrms->vrf_name));
+ } else
+ pbrms->vrf_unchanged = true;
+
+ pbr_map_check(pbrms);
+
+done:
+ return ret;
+}
+
DEFPY (pbr_policy,
pbr_policy_cmd,
"[no] pbr-policy PBRMAP$mapname",
return CMD_SUCCESS;
}
+static void vty_show_pbrms(struct vty *vty,
+ const struct pbr_map_sequence *pbrms, bool detail)
+{
+ char buf[PREFIX_STRLEN];
+ char rbuf[64];
+
+ if (pbrms->reason)
+ pbr_map_reason_string(pbrms->reason, rbuf, sizeof(rbuf));
+
+ vty_out(vty, " Seq: %u rule: %u\n", pbrms->seqno, pbrms->ruleno);
+
+ if (detail)
+ vty_out(vty, " Installed: %" PRIu64 "(%u) Reason: %s\n",
+ pbrms->installed, pbrms->unique,
+ pbrms->reason ? rbuf : "Valid");
+ else
+ vty_out(vty, " Installed: %s Reason: %s\n",
+ pbrms->installed ? "yes" : "no",
+ pbrms->reason ? rbuf : "Valid");
+
+ if (pbrms->src)
+ vty_out(vty, " SRC Match: %s\n",
+ prefix2str(pbrms->src, buf, sizeof(buf)));
+ if (pbrms->dst)
+ vty_out(vty, " DST Match: %s\n",
+ prefix2str(pbrms->dst, buf, sizeof(buf)));
+ if (pbrms->mark)
+ vty_out(vty, " MARK Match: %u\n", pbrms->mark);
+
+ if (pbrms->nhgrp_name) {
+ vty_out(vty, " Nexthop-Group: %s\n", pbrms->nhgrp_name);
+
+ if (detail)
+ vty_out(vty,
+ " Installed: %u(%d) Tableid: %d\n",
+ pbrms->nhs_installed,
+ pbr_nht_get_installed(pbrms->nhgrp_name),
+ pbr_nht_get_table(pbrms->nhgrp_name));
+ else
+ vty_out(vty, " Installed: %s Tableid: %d\n",
+ pbr_nht_get_installed(pbrms->nhgrp_name) ? "yes"
+ : "no",
+ pbr_nht_get_table(pbrms->nhgrp_name));
+
+ } else if (pbrms->nhg) {
+ vty_out(vty, " ");
+ nexthop_group_write_nexthop(vty, pbrms->nhg->nexthop);
+ if (detail)
+ vty_out(vty,
+ " Installed: %u(%d) Tableid: %d\n",
+ pbrms->nhs_installed,
+ pbr_nht_get_installed(pbrms->internal_nhg_name),
+ pbr_nht_get_table(pbrms->internal_nhg_name));
+ else
+ vty_out(vty, " Installed: %s Tableid: %d\n",
+ pbr_nht_get_installed(pbrms->internal_nhg_name)
+ ? "yes"
+ : "no",
+ pbr_nht_get_table(pbrms->internal_nhg_name));
+
+ } else if (pbrms->vrf_unchanged) {
+ vty_out(vty, " VRF Unchanged (use interface vrf)\n");
+ } else if (pbrms->vrf_lookup) {
+ vty_out(vty, " VRF Lookup: %s\n", pbrms->vrf_name);
+ } else {
+ vty_out(vty, " Nexthop-Group: Unknown Installed: no\n");
+ }
+}
+
+static void vty_show_pbr_map(struct vty *vty, const struct pbr_map *pbrm,
+ bool detail)
+{
+ struct pbr_map_sequence *pbrms;
+ struct listnode *node;
+
+ vty_out(vty, " pbr-map %s valid: %s\n", pbrm->name,
+ pbrm->valid ? "yes" : "no");
+
+ for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
+ vty_show_pbrms(vty, pbrms, detail);
+}
+
DEFPY (show_pbr_map,
show_pbr_map_cmd,
"show pbr map [NAME$name] [detail$detail]",
"PBR Map Name\n"
"Detailed information\n")
{
- struct pbr_map_sequence *pbrms;
struct pbr_map *pbrm;
- struct listnode *node;
- char buf[PREFIX_STRLEN];
- char rbuf[64];
RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) {
if (name && strcmp(name, pbrm->name) != 0)
continue;
- vty_out(vty, " pbr-map %s valid: %d\n", pbrm->name,
- pbrm->valid);
-
- for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) {
- if (pbrms->reason)
- pbr_map_reason_string(pbrms->reason, rbuf,
- sizeof(rbuf));
- vty_out(vty,
- " Seq: %u rule: %u Installed: %" PRIu64 "(%u) Reason: %s\n",
- pbrms->seqno, pbrms->ruleno, pbrms->installed,
- pbrms->unique, pbrms->reason ? rbuf : "Valid");
-
- if (pbrms->src)
- vty_out(vty, "\tSRC Match: %s\n",
- prefix2str(pbrms->src, buf,
- sizeof(buf)));
- if (pbrms->dst)
- vty_out(vty, "\tDST Match: %s\n",
- prefix2str(pbrms->dst, buf,
- sizeof(buf)));
- if (pbrms->mark)
- vty_out(vty, "\tMARK Match: %u\n", pbrms->mark);
-
- if (pbrms->nhgrp_name) {
- vty_out(vty,
- "\tNexthop-Group: %s(%u) Installed: %u(%d)\n",
- pbrms->nhgrp_name,
- pbr_nht_get_table(pbrms->nhgrp_name),
- pbrms->nhs_installed,
- pbr_nht_get_installed(
- pbrms->nhgrp_name));
- } else if (pbrms->nhg) {
- vty_out(vty, " ");
- nexthop_group_write_nexthop(
- vty, pbrms->nhg->nexthop);
- vty_out(vty,
- "\tInstalled: %u(%d) Tableid: %d\n",
- pbrms->nhs_installed,
- pbr_nht_get_installed(
- pbrms->internal_nhg_name),
- pbr_nht_get_table(
- pbrms->internal_nhg_name));
- } else {
- vty_out(vty,
- "\tNexthop-Group: Unknown Installed: 0(0)\n");
- }
- }
+ vty_show_pbr_map(vty, pbrm, detail);
}
return CMD_SUCCESS;
}
if (pbrms->mark)
vty_out(vty, " match mark %u\n", pbrms->mark);
+ if (pbrms->vrf_unchanged)
+ vty_out(vty, " set vrf unchanged\n");
+
+ if (pbrms->vrf_lookup)
+ vty_out(vty, " set vrf %s\n", pbrms->vrf_name);
+
if (pbrms->nhgrp_name)
vty_out(vty, " set nexthop-group %s\n", pbrms->nhgrp_name);
install_element(PBRMAP_NODE, &pbr_map_match_mark_cmd);
install_element(PBRMAP_NODE, &pbr_map_nexthop_group_cmd);
install_element(PBRMAP_NODE, &pbr_map_nexthop_cmd);
+ install_element(PBRMAP_NODE, &pbr_map_vrf_cmd);
install_element(VIEW_NODE, &show_pbr_cmd);
install_element(VIEW_NODE, &show_pbr_map_cmd);
install_element(VIEW_NODE, &show_pbr_interface_cmd);