summaryrefslogtreecommitdiff
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/if.c')
-rw-r--r--lib/if.c183
1 files changed, 154 insertions, 29 deletions
diff --git a/lib/if.c b/lib/if.c
index dabf66799d..c887bb6265 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -582,23 +582,39 @@ struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
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)
@@ -1249,8 +1265,6 @@ struct if_link_params *if_link_params_get(struct interface *ifp)
struct if_link_params *iflp =
XCALLOC(MTYPE_IF_LINK_PARAMS, sizeof(struct if_link_params));
- if (iflp == NULL)
- return NULL;
/* Set TE metric equal to standard metric */
iflp->te_metric = ifp->metric;
@@ -1278,8 +1292,6 @@ struct if_link_params *if_link_params_get(struct interface *ifp)
void if_link_params_free(struct interface *ifp)
{
- if (ifp->link_params == NULL)
- return;
XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
}
@@ -1655,33 +1667,98 @@ static int lib_interface_description_destroy(enum nb_event event,
return NB_OK;
}
-/* clang-format off */
+/*
+ * XPath: /frr-interface:lib/interface/state/if-index
+ */
+struct yang_data *lib_interface_state_if_index_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct interface *ifp = list_entry;
+
+ return yang_data_new_int32(xpath, ifp->ifindex);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/state/mtu
+ */
+struct yang_data *lib_interface_state_mtu_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct interface *ifp = list_entry;
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
-/* gcc versions before 5.x miscalculate the size for structs with variable
- * length arrays (they just count it as size 0)
+ return yang_data_new_uint16(xpath, ifp->mtu);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/state/mtu6
+ */
+struct yang_data *lib_interface_state_mtu6_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct interface *ifp = list_entry;
+
+ return yang_data_new_uint32(xpath, ifp->mtu6);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/state/speed
*/
-struct frr_yang_module_info_size3 {
- /* YANG module name. */
- const char *name;
+struct yang_data *lib_interface_state_speed_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct interface *ifp = list_entry;
- /* Northbound callbacks. */
- const struct {
- /* Data path of this YANG node. */
- const char *xpath;
+ return yang_data_new_uint32(xpath, ifp->speed);
+}
- /* Callbacks implemented for this node. */
- struct nb_callbacks cbs;
+/*
+ * XPath: /frr-interface:lib/interface/state/metric
+ */
+struct yang_data *lib_interface_state_metric_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct interface *ifp = list_entry;
- /* Priority - lower priorities are processed first. */
- uint32_t priority;
- } nodes[3];
-};
+ return yang_data_new_uint32(xpath, ifp->metric);
+}
-const struct frr_yang_module_info_size3 frr_interface_info_size3 asm("frr_interface_info") = {
-#else
+/*
+ * XPath: /frr-interface:lib/interface/state/flags
+ */
+struct yang_data *lib_interface_state_flags_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ /* TODO: implement me. */
+ return NULL;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/state/type
+ */
+struct yang_data *lib_interface_state_type_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ /* TODO: implement me. */
+ return NULL;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/state/phy-address
+ */
+struct yang_data *
+lib_interface_state_phy_address_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct interface *ifp = list_entry;
+ struct ethaddr macaddr;
+
+ memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
+
+ return yang_data_new_mac(xpath, &macaddr);
+}
+
+/* clang-format off */
const struct frr_yang_module_info frr_interface_info = {
-#endif
.name = "frr-interface",
.nodes = {
{
@@ -1704,6 +1781,54 @@ const struct frr_yang_module_info frr_interface_info = {
},
},
{
+ .xpath = "/frr-interface:lib/interface/state/if-index",
+ .cbs = {
+ .get_elem = lib_interface_state_if_index_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/mtu",
+ .cbs = {
+ .get_elem = lib_interface_state_mtu_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/mtu6",
+ .cbs = {
+ .get_elem = lib_interface_state_mtu6_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/speed",
+ .cbs = {
+ .get_elem = lib_interface_state_speed_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/metric",
+ .cbs = {
+ .get_elem = lib_interface_state_metric_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/flags",
+ .cbs = {
+ .get_elem = lib_interface_state_flags_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/type",
+ .cbs = {
+ .get_elem = lib_interface_state_type_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/state/phy-address",
+ .cbs = {
+ .get_elem = lib_interface_state_phy_address_get_elem,
+ }
+ },
+ {
.xpath = NULL,
},
}