diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/zebra_vrf.c | 38 | ||||
-rw-r--r-- | zebra/zebra_vrf.h | 1 | ||||
-rw-r--r-- | zebra/zebra_vty.c | 44 | ||||
-rw-r--r-- | zebra/zebra_vxlan.c | 2 |
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. */ |