summaryrefslogtreecommitdiff
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/if.c')
-rw-r--r--lib/if.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/lib/if.c b/lib/if.c
index 7866ddb8c4..2541e6e45a 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -48,8 +48,8 @@ RB_GENERATE(if_index_head, interface, index_entry, if_cmp_index_func);
DEFINE_QOBJ_TYPE(interface)
-DEFINE_HOOK(if_add, (struct interface *ifp), (ifp))
-DEFINE_KOOH(if_del, (struct interface *ifp), (ifp))
+DEFINE_HOOK(if_add, (struct interface * ifp), (ifp))
+DEFINE_KOOH(if_del, (struct interface * ifp), (ifp))
/* List of interfaces in only the default VRF */
int ptm_enable = 0;
@@ -152,7 +152,7 @@ struct interface *if_create(const char *name, vrf_id_t vrf_id)
SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
QOBJ_REG(ifp, interface);
- hook_call(if_add, ifp);
+ hook_call(if_add, ifp);
return ifp;
}
@@ -181,7 +181,7 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
/* Delete interface structure. */
void if_delete_retain(struct interface *ifp)
{
- hook_call(if_del, ifp);
+ hook_call(if_del, ifp);
QOBJ_UNREG(ifp);
/* Free connected address list */
@@ -225,7 +225,7 @@ struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id)
if (vrf_id == VRF_UNKNOWN) {
struct interface *ifp;
- RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
ifp = if_lookup_by_index(ifindex, vrf->vrf_id);
if (ifp)
return ifp;
@@ -384,29 +384,34 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty)
{
struct interface *ifp;
+ ifp = if_lookup_by_name(name, vrf_id);
+ if (ifp)
+ return ifp;
+ /* Not Found on same VRF. If the interface command
+ * was entered in vty without a VRF (passed as VRF_DEFAULT),
+ * accept the ifp we found. If a vrf was entered and there is
+ * a mismatch, reject it if from vty.
+ */
ifp = if_lookup_by_name_all_vrf(name);
- if (ifp) {
- if (ifp->vrf_id == vrf_id)
+ if (!ifp)
+ return if_create(name, vrf_id);
+ if (vty) {
+ if (vrf_id == VRF_DEFAULT)
return ifp;
-
- /* Found a match on a different VRF. If the interface command
- * was entered in vty without a VRF (passed as VRF_DEFAULT),
- * accept the ifp we found. If a vrf was entered and there is
- * a mismatch, reject it if from vty. If it came from the kernel
- * or by way of zclient, believe it and update the ifp
- * accordingly.
- */
- if (vty) {
- if (vrf_id == VRF_DEFAULT)
- return ifp;
- return NULL;
- } else {
- if_update_to_new_vrf(ifp, vrf_id);
- return ifp;
- }
+ return NULL;
}
-
- return if_create(name, vrf_id);
+ /* if vrf backend uses NETNS, then
+ * this should not be considered as an update
+ * then create the new interface
+ */
+ if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns(vrf_id))
+ return if_create(name, vrf_id);
+ /* If it came from the kernel
+ * or by way of zclient, believe it and update
+ * the ifp accordingly.
+ */
+ if_update_to_new_vrf(ifp, vrf_id);
+ return ifp;
}
void if_set_index(struct interface *ifp, ifindex_t ifindex)
@@ -471,6 +476,12 @@ int if_is_loopback(struct interface *ifp)
return (ifp->flags & (IFF_LOOPBACK | IFF_NOXMIT | IFF_VIRTUAL));
}
+/* Check interface is VRF */
+int if_is_vrf(struct interface *ifp)
+{
+ return CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
+}
+
/* Does this interface support broadcast ? */
int if_is_broadcast(struct interface *ifp)
{
@@ -1064,7 +1075,7 @@ ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
if (! rn)
return NULL;
-
+
ifp = rn->info;
route_unlock_node (rn);
return ifp;
@@ -1078,7 +1089,9 @@ void if_terminate(struct vrf *vrf)
{
struct interface *ifp;
- while ((ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name)) != NULL) {
+ while (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
+ ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name);
+
if (ifp->node) {
ifp->node->info = NULL;
route_unlock_node(ifp->node);