summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-02-08 11:46:29 +0100
committerGitHub <noreply@github.com>2018-02-08 11:46:29 +0100
commit8e71b98f72e843d4910abd02410f07fe1e6565cc (patch)
treea84f92632eb0deed948f6b961c489573ede1ac0b /lib
parent25236dd35df008a1484f2605299c8228ea1cfc5b (diff)
parent9d00a48754440cc9d4674e9b9405642edd983f0f (diff)
Merge pull request #1654 from mkanjari/evpn-symm-routing-enhancements
Evpn symmetric routing enhancements
Diffstat (limited to 'lib')
-rw-r--r--lib/log.c3
-rw-r--r--lib/vrf.c41
-rw-r--r--lib/vrf.h29
-rw-r--r--lib/zclient.c10
-rw-r--r--lib/zclient.h9
5 files changed, 78 insertions, 14 deletions
diff --git a/lib/log.c b/lib/log.c
index bf65ac7c7d..66be533e84 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -943,6 +943,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK),
DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI),
DESC_ENTRY(ZEBRA_ADVERTISE_DEFAULT_GW),
+ DESC_ENTRY(ZEBRA_ADVERTISE_SUBNET),
DESC_ENTRY(ZEBRA_VNI_ADD),
DESC_ENTRY(ZEBRA_VNI_DEL),
DESC_ENTRY(ZEBRA_L3VNI_ADD),
@@ -951,6 +952,8 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_REMOTE_VTEP_DEL),
DESC_ENTRY(ZEBRA_MACIP_ADD),
DESC_ENTRY(ZEBRA_MACIP_DEL),
+ DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_ADD),
+ DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_DEL),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_ADD),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_DEL),
DESC_ENTRY(ZEBRA_PW_ADD),
diff --git a/lib/vrf.c b/lib/vrf.c
index 2fa3a9c0ef..2e15fa2f5c 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -141,7 +141,9 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
return vrf;
}
-/* Delete a VRF. This is called in vrf_terminate(). */
+/* Delete a VRF. This is called when the underlying VRF goes away, a
+ * pre-configured VRF is deleted or when shutting down (vrf_terminate()).
+ */
void vrf_delete(struct vrf *vrf)
{
if (debug_vrf)
@@ -150,6 +152,23 @@ void vrf_delete(struct vrf *vrf)
if (vrf_is_enabled(vrf))
vrf_disable(vrf);
+ /* If the VRF is user configured, it'll stick around, just remove
+ * the ID mapping. Interfaces assigned to this VRF should've been
+ * removed already as part of the VRF going down.
+ */
+ if (vrf_is_user_cfged(vrf)) {
+ if (vrf->vrf_id != VRF_UNKNOWN) {
+ /* Delete any VRF interfaces - should be only
+ * the VRF itself, other interfaces should've
+ * been moved out of the VRF.
+ */
+ if_terminate(vrf);
+ RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
+ vrf->vrf_id = VRF_UNKNOWN;
+ }
+ return;
+ }
+
if (vrf_master.vrf_delete_hook)
(*vrf_master.vrf_delete_hook)(vrf);
@@ -173,14 +192,6 @@ struct vrf *vrf_lookup_by_id(vrf_id_t vrf_id)
}
/*
- * Check whether the VRF is enabled.
- */
-static int vrf_is_enabled(struct vrf *vrf)
-{
- return vrf && CHECK_FLAG(vrf->status, VRF_ACTIVE);
-}
-
-/*
* Enable a VRF - that is, let the VRF be ready to use.
* The VRF_ENABLE_HOOK callback will be called to inform
* that they can allocate resources in this VRF.
@@ -408,10 +419,16 @@ void vrf_terminate(void)
zlog_debug("%s: Shutting down vrf subsystem",
__PRETTY_FUNCTION__);
- while ((vrf = RB_ROOT(vrf_id_head, &vrfs_by_id)) != NULL)
+ while ((vrf = RB_ROOT(vrf_id_head, &vrfs_by_id)) != NULL) {
+ /* Clear configured flag and invoke delete. */
+ UNSET_FLAG(vrf->status, VRF_CONFIGURED);
vrf_delete(vrf);
- while ((vrf = RB_ROOT(vrf_name_head, &vrfs_by_name)) != NULL)
+ }
+ while ((vrf = RB_ROOT(vrf_name_head, &vrfs_by_name)) != NULL) {
+ /* Clear configured flag and invoke delete. */
+ UNSET_FLAG(vrf->status, VRF_CONFIGURED);
vrf_delete(vrf);
+ }
}
/* Create a socket for the VRF. */
@@ -473,6 +490,8 @@ DEFUN_NOSH (no_vrf,
return CMD_WARNING_CONFIG_FAILED;
}
+ /* Clear configured flag and invoke delete. */
+ UNSET_FLAG(vrfp->status, VRF_CONFIGURED);
vrf_delete(vrfp);
return CMD_SUCCESS;
diff --git a/lib/vrf.h b/lib/vrf.h
index 7e625769e7..99c048c702 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -75,7 +75,8 @@ struct vrf {
/* Zebra internal VRF status */
u_char status;
-#define VRF_ACTIVE (1 << 0)
+#define VRF_ACTIVE (1 << 0) /* VRF is up in kernel */
+#define VRF_CONFIGURED (1 << 1) /* VRF has some FRR configuration */
/* Interfaces belonging to this VRF */
struct if_name_head ifaces_by_name;
@@ -120,6 +121,32 @@ extern vrf_id_t vrf_name_to_id(const char *);
} while (0)
/*
+ * Check whether the VRF is enabled.
+ */
+static inline int vrf_is_enabled(struct vrf *vrf)
+{
+ return vrf && CHECK_FLAG(vrf->status, VRF_ACTIVE);
+}
+
+/* check if the vrf is user configured */
+static inline int vrf_is_user_cfged(struct vrf *vrf)
+{
+ return vrf && CHECK_FLAG(vrf->status, VRF_CONFIGURED);
+}
+
+/* Mark that VRF has user configuration */
+static inline void vrf_set_user_cfged(struct vrf *vrf)
+{
+ SET_FLAG(vrf->status, VRF_CONFIGURED);
+}
+
+/* Mark that VRF no longer has any user configuration */
+static inline void vrf_reset_user_cfged(struct vrf *vrf)
+{
+ UNSET_FLAG(vrf->status, VRF_CONFIGURED);
+}
+
+/*
* Utilities to obtain the user data
*/
diff --git a/lib/zclient.c b/lib/zclient.c
index 6f770c66e4..0c29b523bf 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -2333,6 +2333,16 @@ static int zclient_read(struct thread *thread)
(*zclient->local_macip_del)(command, zclient, length,
vrf_id);
break;
+ case ZEBRA_IP_PREFIX_ROUTE_ADD:
+ if (zclient->local_ip_prefix_add)
+ (*zclient->local_ip_prefix_add)(command, zclient,
+ length, vrf_id);
+ break;
+ case ZEBRA_IP_PREFIX_ROUTE_DEL:
+ if (zclient->local_ip_prefix_del)
+ (*zclient->local_ip_prefix_del)(command, zclient,
+ length, vrf_id);
+ break;
case ZEBRA_PW_STATUS_UPDATE:
if (zclient->pw_status_update)
(*zclient->pw_status_update)(command, zclient, length,
diff --git a/lib/zclient.h b/lib/zclient.h
index bd4d32d2bd..5c7c5d6d5b 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -109,6 +109,7 @@ typedef enum {
ZEBRA_FEC_UNREGISTER,
ZEBRA_FEC_UPDATE,
ZEBRA_ADVERTISE_DEFAULT_GW,
+ ZEBRA_ADVERTISE_SUBNET,
ZEBRA_ADVERTISE_ALL_VNI,
ZEBRA_VNI_ADD,
ZEBRA_VNI_DEL,
@@ -118,6 +119,8 @@ typedef enum {
ZEBRA_REMOTE_VTEP_DEL,
ZEBRA_MACIP_ADD,
ZEBRA_MACIP_DEL,
+ ZEBRA_IP_PREFIX_ROUTE_ADD,
+ ZEBRA_IP_PREFIX_ROUTE_DEL,
ZEBRA_REMOTE_MACIP_ADD,
ZEBRA_REMOTE_MACIP_DEL,
ZEBRA_PW_ADD,
@@ -204,6 +207,8 @@ struct zclient {
int (*local_vni_del)(int, struct zclient *, uint16_t, vrf_id_t);
int (*local_l3vni_add)(int, struct zclient *, uint16_t, vrf_id_t);
int (*local_l3vni_del)(int, struct zclient *, uint16_t, vrf_id_t);
+ void (*local_ip_prefix_add)(int, struct zclient *, uint16_t, vrf_id_t);
+ void (*local_ip_prefix_del)(int, struct zclient *, uint16_t, vrf_id_t);
int (*local_macip_add)(int, struct zclient *, uint16_t, vrf_id_t);
int (*local_macip_del)(int, struct zclient *, uint16_t, vrf_id_t);
int (*pw_status_update)(int, struct zclient *, uint16_t, vrf_id_t);
@@ -343,8 +348,8 @@ enum zapi_route_notify_owner {
};
/* Zebra MAC types */
-#define ZEBRA_MAC_TYPE_STICKY 0x01 /* Sticky MAC*/
-#define ZEBRA_MAC_TYPE_GW 0x02 /* gateway (SVI) mac*/
+#define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky MAC*/
+#define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/
struct zclient_options {
bool receive_notify;