]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: fix config after exit from vrf 8778/head
authorIgor Ryzhov <iryzhov@nfware.com>
Wed, 2 Jun 2021 14:27:02 +0000 (17:27 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Fri, 4 Jun 2021 16:02:32 +0000 (19:02 +0300)
When the VRF node is exited using "exit" or "quit", there's still a VRF
pointer stored in the vty context. If you try to configure some router
related command, it will be applied to the previous VRF instead of the
default VRF. For example:

```
(config)# vrf test
(config-vrf)# ip router-id 1.1.1.1
(config-vrf)# do show run
...
!
vrf test
 ip router-id 1.1.1.1
 exit-vrf
!
...
(config-vrf)# exit
(config)# ip router-id 2.2.2.2
(config)# do show run
...
!
vrf test
 ip router-id 2.2.2.2
 exit-vrf
!
...
```

`vrf-exit` works correctly, because it stores a pointer to the default
VRF into the vty context (but weirdly keeping the VRF_NODE instead of
changing it to CONFIG_NODE).

Instead of relying on the behavior of exit function, always use the
default VRF when in CONFIG_NODE.

Another problem is missing `VTY_CHECK_CONTEXT`. If someone deletes the
VRF in which node the user enters the command, then zebra applies the
command to the default VRF instead of throwing an error.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
lib/vrf.c
zebra/zebra_vrf.h

index a44cc50f9234954cc06aa56dd1d41b4161e94d83..de29f45f8f1377c72a99e1ef4bf1319e71735d3b 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -780,8 +780,6 @@ DEFUN_NOSH(vrf_exit,
           "exit-vrf",
           "Exit current mode and down to previous mode\n")
 {
-       /* We have to set vrf context to default vrf */
-       VTY_PUSH_CONTEXT(VRF_NODE, vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME));
        cmd_exit(vty);
        return CMD_SUCCESS;
 }
index b2b0fcfbb2a837e41fc43600e0adf0174545e477..57dd0c20ad7d37e5365f467ba8f68177f886f947 100644 (file)
@@ -192,8 +192,13 @@ struct zebra_vrf {
  * special macro to allow us to get the correct zebra_vrf
  */
 #define ZEBRA_DECLVAR_CONTEXT(A, B)                                            \
-       struct vrf *A = VTY_GET_CONTEXT(vrf);                                  \
-       struct zebra_vrf *B = (A) ? A->info : vrf_info_lookup(VRF_DEFAULT)
+       struct vrf *A;                                                         \
+       if (vty->node == CONFIG_NODE)                                          \
+               A = vrf_lookup_by_id(VRF_DEFAULT);                             \
+       else                                                                   \
+               A = VTY_GET_CONTEXT(vrf);                                      \
+       VTY_CHECK_CONTEXT(A);                                                  \
+       struct zebra_vrf *B = A->info
 
 static inline vrf_id_t zvrf_id(struct zebra_vrf *zvrf)
 {