summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/zebra_vrf.c38
-rw-r--r--zebra/zebra_vrf.h1
-rw-r--r--zebra/zebra_vty.c44
-rw-r--r--zebra/zebra_vxlan.c2
4 files changed, 75 insertions, 10 deletions
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 54c9f573c..4310bd394 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -351,6 +351,37 @@ static int zebra_vrf_delete(struct vrf *vrf)
return 0;
}
+/* Return if this VRF has any FRR configuration or not.
+ * IMPORTANT: This function needs to be updated when additional configuration
+ * is added for a VRF.
+ */
+int zebra_vrf_has_config(struct zebra_vrf *zvrf)
+{
+ afi_t afi;
+ safi_t safi;
+ struct route_table *stable;
+
+ /* NOTE: This is a don't care for the default VRF, but we go through
+ * the motions to keep things consistent.
+ */
+ /* Any static routes? */
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+ stable = zvrf->stable[afi][safi];
+ if (!stable)
+ continue;
+ if (route_table_count(stable))
+ return 1;
+ }
+ }
+
+ /* EVPN L3-VNI? */
+ if (zvrf->l3vni)
+ return 1;
+
+ return 0;
+}
+
/* Lookup the routing table in a VRF based on both VRF-Id and table-id.
* NOTE: Table-id is relevant only in the Default VRF.
*/
@@ -565,14 +596,15 @@ static int vrf_config_write(struct vty *vty)
if (vrf_is_user_cfged(vrf)) {
vty_out(vty, "vrf %s\n", zvrf_name(zvrf));
+ if (zvrf->l3vni)
+ vty_out(vty, " vni %u\n", zvrf->l3vni);
+ vty_out(vty, "!\n");
+ }
static_config(vty, zvrf, AFI_IP, SAFI_UNICAST, "ip route");
static_config(vty, zvrf, AFI_IP, SAFI_MULTICAST, "ip mroute");
static_config(vty, zvrf, AFI_IP6, SAFI_UNICAST, "ipv6 route");
- if (vrf->vrf_id != VRF_DEFAULT && zvrf->l3vni)
- vty_out(vty, " vni %u\n", zvrf->l3vni);
-
if (vrf->vrf_id != VRF_DEFAULT)
vty_out(vty, "!\n");
}
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index c7a0717ee..fe7e77e8b 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -149,5 +149,6 @@ extern struct route_table *zebra_vrf_static_table(afi_t, safi_t,
struct zebra_vrf *zvrf);
extern struct route_table *
zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id, vrf_id_t vrf_id);
+extern int zebra_vrf_has_config(struct zebra_vrf *zvrf);
extern void zebra_vrf_init(void);
#endif
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index bc6a18d3b..89ae1e81c 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -231,13 +231,19 @@ static int zebra_static_route_leak(struct vty *vty,
type = STATIC_IPV6_GATEWAY;
}
- if (!negate)
+ if (!negate) {
static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
bh_type, tag, distance, zvrf, nh_zvrf,
&snh_label);
- else
+ /* Mark as having FRR configuration */
+ vrf_set_user_cfged(zvrf->vrf);
+ } else {
static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
tag, distance, zvrf, &snh_label);
+ /* If no other FRR config for this VRF, mark accordingly. */
+ if (!zebra_vrf_has_config(zvrf))
+ vrf_reset_user_cfged(zvrf->vrf);
+ }
return CMD_SUCCESS;
}
@@ -247,19 +253,39 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
const char *mask_str, const char *src_str,
const char *gate_str, const char *ifname,
const char *flag_str, const char *tag_str,
- const char *distance_str, const char *vrf_id_str,
+ const char *distance_str, const char *vrf_name,
const char *label_str)
{
struct zebra_vrf *zvrf;
+ struct vrf *vrf;
/* VRF id */
- zvrf = zebra_vrf_lookup_by_name(vrf_id_str);
+ zvrf = zebra_vrf_lookup_by_name(vrf_name);
- if (!zvrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf_id_str);
+ /* When trying to delete, the VRF must exist. */
+ if (negate && !zvrf) {
+ vty_out(vty, "%% vrf %s is not defined\n", vrf_name);
return CMD_WARNING_CONFIG_FAILED;
}
+ /* When trying to create, create the VRF if it doesn't exist.
+ * Note: The VRF isn't active until we hear about it from the kernel.
+ */
+ if (!zvrf) {
+ vrf = vrf_get(VRF_UNKNOWN, vrf_name);
+ if (!vrf) {
+ vty_out(vty, "%% Could not create vrf %s\n", vrf_name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ zvrf = vrf->info;
+ if (!zvrf) {
+ vty_out(vty, "%% Could not create vrf-info %s\n",
+ vrf_name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ /* Mark as having FRR configuration */
+ vrf_set_user_cfged(vrf);
+ }
return zebra_static_route_leak(vty, zvrf, zvrf, afi, safi,
negate, dest_str, mask_str, src_str,
gate_str, ifname, flag_str, tag_str,
@@ -2269,6 +2295,8 @@ DEFUN (show_vrf,
else
vty_out(vty, "id %u table %u", zvrf_id(zvrf),
zvrf->table_id);
+ if (vrf_is_user_cfged(vrf))
+ vty_out(vty, " (configured)");
vty_out(vty, "\n");
}
@@ -2372,6 +2400,10 @@ DEFUN (no_vrf_vni_mapping,
return CMD_WARNING;
}
+ /* If no other FRR config for this VRF, mark accordingly. */
+ if (!zebra_vrf_has_config(zvrf))
+ vrf_reset_user_cfged(vrf);
+
return CMD_SUCCESS;
}
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 750dfc4ea..fb1aebecc 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -3801,7 +3801,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, vrf_id);
+ zclient_create_header(s, cmd, vrf_id);
stream_put(s, p, sizeof(struct prefix));
/* Write packet size. */