]> git.proxmox.com Git - mirror_frr.git/blobdiff - pbrd/pbr_vty.c
pbrd: use yes/no for pbr map validity vty output
[mirror_frr.git] / pbrd / pbr_vty.c
index e0fd147b0e8dbdcf425e64ee2d537a1f5f5b2659..c1922d87288a1020132d697b26e5f112b509a7a1 100644 (file)
@@ -127,11 +127,16 @@ DEFPY(pbr_map_match_src, pbr_map_match_src_cmd,
        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);
@@ -145,7 +150,7 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
        "[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")
 {
@@ -154,11 +159,16 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
        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;
 
-               if (!pbrms->dst)
-                       pbrms->dst = prefix_new();
+                       vty_out(vty,
+                               "A `match dst-ip XX` command already exists, please remove that first\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+
+               pbrms->dst = prefix_new();
                prefix_copy(pbrms->dst, prefix);
        } else
                prefix_free(&pbrms->dst);
@@ -183,24 +193,33 @@ DEFPY(pbr_map_match_mark, pbr_map_match_mark_cmd,
 #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;
@@ -211,19 +230,25 @@ DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd,
                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;
                }
@@ -231,7 +256,7 @@ DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd,
                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;
                        }
 
@@ -268,7 +293,12 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd,
 
        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;
        }
 
@@ -345,7 +375,7 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd,
 
                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;
                }
 
@@ -372,6 +402,61 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd,
        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",
@@ -439,6 +524,88 @@ DEFPY (show_pbr,
        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]",
@@ -448,63 +615,13 @@ DEFPY (show_pbr_map,
        "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;
 }
@@ -662,6 +779,12 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty,
        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);
 
@@ -737,6 +860,7 @@ void pbr_vty_init(void)
        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);