return NULL;
}
-void if_set_index(struct interface *ifp, ifindex_t ifindex)
+int if_set_index(struct interface *ifp, ifindex_t ifindex)
{
struct vrf *vrf;
+ if (ifp->ifindex == ifindex)
+ return 0;
+
vrf = vrf_get(ifp->vrf_id, NULL);
assert(vrf);
- if (ifp->ifindex == ifindex)
- return;
+ /*
+ * If there is already an interface with this ifindex, we will collide
+ * on insertion, so don't even try.
+ */
+ if (if_lookup_by_ifindex(ifindex, ifp->vrf_id))
+ return -1;
if (ifp->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(vrf, ifp);
ifp->ifindex = ifindex;
- if (ifp->ifindex != IFINDEX_INTERNAL)
- IFINDEX_RB_INSERT(vrf, ifp)
+ if (ifp->ifindex != IFINDEX_INTERNAL) {
+ /*
+ * This should never happen, since we checked if there was
+ * already an interface with the desired ifindex at the top of
+ * the function. Nevertheless.
+ */
+ if (IFINDEX_RB_INSERT(vrf, ifp))
+ return -1;
+ }
+
+ return 0;
}
void if_set_name(struct interface *ifp, const char *name)
RB_PROTOTYPE(if_index_head, interface, index_entry, if_cmp_index_func)
DECLARE_QOBJ_TYPE(interface)
-#define IFNAME_RB_INSERT(vrf, ifp) \
- if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp))) \
- flog_err(EC_LIB_INTERFACE, \
- "%s(%s): corruption detected -- interface with this " \
- "name exists already in VRF %u!", \
- __func__, (ifp)->name, (ifp)->vrf_id);
-
-#define IFNAME_RB_REMOVE(vrf, ifp) \
- if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL) \
- flog_err(EC_LIB_INTERFACE, \
- "%s(%s): corruption detected -- interface with this " \
- "name doesn't exist in VRF %u!", \
- __func__, (ifp)->name, (ifp)->vrf_id);
-
-#define IFINDEX_RB_INSERT(vrf, ifp) \
- if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp))) \
- flog_err(EC_LIB_INTERFACE, \
- "%s(%u): corruption detected -- interface with this " \
- "ifindex exists already in VRF %u!", \
- __func__, (ifp)->ifindex, (ifp)->vrf_id);
-
-#define IFINDEX_RB_REMOVE(vrf, ifp) \
- if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL) \
- flog_err(EC_LIB_INTERFACE, \
- "%s(%u): corruption detected -- interface with this " \
- "ifindex doesn't exist in VRF %u!", \
- __func__, (ifp)->ifindex, (ifp)->vrf_id);
+#define IFNAME_RB_INSERT(vrf, ifp) \
+ ({ \
+ struct interface *_iz = \
+ RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp)); \
+ if (_iz) \
+ flog_err( \
+ EC_LIB_INTERFACE, \
+ "%s(%s): corruption detected -- interface with this " \
+ "name exists already in VRF %u!", \
+ __func__, (ifp)->name, (ifp)->vrf_id); \
+ _iz; \
+ })
+
+#define IFNAME_RB_REMOVE(vrf, ifp) \
+ ({ \
+ struct interface *_iz = \
+ RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)); \
+ if (_iz == NULL) \
+ flog_err( \
+ EC_LIB_INTERFACE, \
+ "%s(%s): corruption detected -- interface with this " \
+ "name doesn't exist in VRF %u!", \
+ __func__, (ifp)->name, (ifp)->vrf_id); \
+ _iz; \
+ })
+
+
+#define IFINDEX_RB_INSERT(vrf, ifp) \
+ ({ \
+ struct interface *_iz = RB_INSERT( \
+ if_index_head, &vrf->ifaces_by_index, (ifp)); \
+ if (_iz) \
+ flog_err( \
+ EC_LIB_INTERFACE, \
+ "%s(%u): corruption detected -- interface with this " \
+ "ifindex exists already in VRF %u!", \
+ __func__, (ifp)->ifindex, (ifp)->vrf_id); \
+ _iz; \
+ })
+
+#define IFINDEX_RB_REMOVE(vrf, ifp) \
+ ({ \
+ struct interface *_iz = RB_REMOVE( \
+ if_index_head, &vrf->ifaces_by_index, (ifp)); \
+ if (_iz == NULL) \
+ flog_err( \
+ EC_LIB_INTERFACE, \
+ "%s(%u): corruption detected -- interface with this " \
+ "ifindex doesn't exist in VRF %u!", \
+ __func__, (ifp)->ifindex, (ifp)->vrf_id); \
+ _iz; \
+ })
#define FOR_ALL_INTERFACES(vrf, ifp) \
if (vrf) \
extern struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
/* Sets the index and adds to index list */
-extern void if_set_index(struct interface *ifp, ifindex_t ifindex);
+extern int if_set_index(struct interface *ifp, ifindex_t ifindex);
/* Sets the name and adds to name list */
extern void if_set_name(struct interface *ifp, const char *name);