summaryrefslogtreecommitdiffstats
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/if.c140
1 files changed, 72 insertions, 68 deletions
diff --git a/lib/if.c b/lib/if.c
index 48c01af..a8ceac7 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -42,15 +42,14 @@ 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));
-static struct interface_master{
- int (*create_hook)(struct interface *ifp);
- int (*up_hook)(struct interface *ifp);
- int (*down_hook)(struct interface *ifp);
- int (*destroy_hook)(struct interface *ifp);
-} ifp_master = { 0, };
+DEFINE_HOOK(if_real, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_unreal, (struct interface *ifp), (ifp));
+
+DEFINE_HOOK(if_up, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_down, (struct interface *ifp), (ifp));
/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
@@ -165,8 +164,7 @@ static struct interface *if_new(struct vrf *vrf)
ifp->vrf = vrf;
- ifp->connected = list_new();
- ifp->connected->del = ifp_connected_free;
+ if_connected_init(ifp->connected);
ifp->nbr_connected = list_new();
ifp->nbr_connected->del = (void (*)(void *))nbr_connected_free;
@@ -180,14 +178,12 @@ static struct interface *if_new(struct vrf *vrf)
void if_new_via_zapi(struct interface *ifp)
{
- if (ifp_master.create_hook)
- (*ifp_master.create_hook)(ifp);
+ hook_call(if_real, ifp);
}
void if_destroy_via_zapi(struct interface *ifp)
{
- if (ifp_master.destroy_hook)
- (*ifp_master.destroy_hook)(ifp);
+ hook_call(if_unreal, ifp);
ifp->oldifindex = ifp->ifindex;
if_set_index(ifp, IFINDEX_INTERNAL);
@@ -198,14 +194,12 @@ void if_destroy_via_zapi(struct interface *ifp)
void if_up_via_zapi(struct interface *ifp)
{
- if (ifp_master.up_hook)
- (*ifp_master.up_hook)(ifp);
+ hook_call(if_up, ifp);
}
void if_down_via_zapi(struct interface *ifp)
{
- if (ifp_master.down_hook)
- (*ifp_master.down_hook)(ifp);
+ hook_call(if_down, ifp);
}
static struct interface *if_create_name(const char *name, struct vrf *vrf)
@@ -248,11 +242,14 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
/* Delete interface structure. */
void if_delete_retain(struct interface *ifp)
{
+ struct connected *ifc;
+
hook_call(if_del, ifp);
QOBJ_UNREG(ifp);
/* Free connected address list */
- list_delete_all_node(ifp->connected);
+ while ((ifc = if_connected_pop(ifp->connected)))
+ ifp_connected_free(ifc);
/* Free connected nbr address list */
list_delete_all_node(ifp->nbr_connected);
@@ -270,7 +267,7 @@ void if_delete(struct interface **ifp)
if_delete_retain(ptr);
- list_delete(&ptr->connected);
+ if_connected_fini(ptr->connected);
list_delete(&ptr->nbr_connected);
if_link_params_free(ptr);
@@ -367,8 +364,7 @@ struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id)
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface if_tmp;
- if (!vrf || !name
- || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
+ if (!vrf || !name || strnlen(name, IFNAMSIZ) == IFNAMSIZ)
return NULL;
strlcpy(if_tmp.name, name, sizeof(if_tmp.name));
@@ -379,7 +375,7 @@ struct interface *if_lookup_by_name_vrf(const char *name, struct vrf *vrf)
{
struct interface if_tmp;
- if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
+ if (!name || strnlen(name, IFNAMSIZ) == IFNAMSIZ)
return NULL;
strlcpy(if_tmp.name, name, sizeof(if_tmp.name));
@@ -391,7 +387,7 @@ static struct interface *if_lookup_by_name_all_vrf(const char *name)
struct vrf *vrf;
struct interface *ifp;
- if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
+ if (!name || strnlen(name, IFNAMSIZ) == IFNAMSIZ)
return NULL;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
@@ -433,7 +429,6 @@ struct interface *if_lookup_address_local(const void *src, int family,
vrf_id_t vrf_id)
{
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- struct listnode *cnode;
struct interface *ifp, *best_down = NULL;
struct prefix *p;
struct connected *c;
@@ -442,7 +437,7 @@ struct interface *if_lookup_address_local(const void *src, int family,
return NULL;
FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
p = c->address;
if (!p || p->family != family)
@@ -474,7 +469,6 @@ struct connected *if_lookup_address(const void *matchaddr, int family,
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct prefix addr;
int bestlen = 0;
- struct listnode *cnode;
struct interface *ifp;
struct connected *c;
struct connected *match;
@@ -493,7 +487,7 @@ struct connected *if_lookup_address(const void *matchaddr, int family,
match = NULL;
FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (c->address && (c->address->family == AF_INET)
&& prefix_match(CONNECTED_PREFIX(c), &addr)
&& (c->address->prefixlen > bestlen)) {
@@ -509,12 +503,11 @@ struct connected *if_lookup_address(const void *matchaddr, int family,
struct interface *if_lookup_prefix(const struct prefix *prefix, vrf_id_t vrf_id)
{
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- struct listnode *cnode;
struct interface *ifp;
struct connected *c;
FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (prefix_cmp(c->address, prefix) == 0) {
return ifp;
}
@@ -781,10 +774,9 @@ const char *if_flag_dump(unsigned long flag)
/* For debugging */
static void if_dump(const struct interface *ifp)
{
- struct listnode *node;
- struct connected *c __attribute__((unused));
+ const struct connected *c;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c))
+ frr_each (if_connected_const, ifp->connected, c)
zlog_info(
"Interface %s vrf %s(%u) index %d metric %d mtu %d mtu6 %d %s",
ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
@@ -911,11 +903,10 @@ static int connected_same_prefix(const struct prefix *p1,
/* count the number of connected addresses that are in the given family */
unsigned int connected_count_by_family(struct interface *ifp, int family)
{
- struct listnode *cnode;
struct connected *connected;
unsigned int cnt = 0;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected))
+ frr_each (if_connected, ifp->connected, connected)
if (connected->address->family == family)
cnt++;
@@ -925,14 +916,9 @@ unsigned int connected_count_by_family(struct interface *ifp, int family)
struct connected *connected_lookup_prefix_exact(struct interface *ifp,
const struct prefix *p)
{
- struct listnode *node;
- struct listnode *next;
struct connected *ifc;
- for (node = listhead(ifp->connected); node; node = next) {
- ifc = listgetdata(node);
- next = node->next;
-
+ frr_each (if_connected, ifp->connected, ifc) {
if (connected_same_prefix(ifc->address, p))
return ifc;
}
@@ -942,17 +928,12 @@ struct connected *connected_lookup_prefix_exact(struct interface *ifp,
struct connected *connected_delete_by_prefix(struct interface *ifp,
struct prefix *p)
{
- struct listnode *node;
- struct listnode *next;
struct connected *ifc;
/* In case of same prefix come, replace it with new one. */
- for (node = listhead(ifp->connected); node; node = next) {
- ifc = listgetdata(node);
- next = node->next;
-
+ frr_each_safe (if_connected, ifp->connected, ifc) {
if (connected_same_prefix(ifc->address, p)) {
- listnode_delete(ifp->connected, ifc);
+ if_connected_del(ifp->connected, ifc);
return ifc;
}
}
@@ -964,13 +945,12 @@ struct connected *connected_delete_by_prefix(struct interface *ifp,
struct connected *connected_lookup_prefix(struct interface *ifp,
const struct prefix *addr)
{
- struct listnode *cnode;
struct connected *c;
struct connected *match;
match = NULL;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (c->address && (c->address->family == addr->family)
&& prefix_match(CONNECTED_PREFIX(c), addr)
&& (!match
@@ -1001,16 +981,15 @@ struct connected *connected_add_by_prefix(struct interface *ifp,
}
/* Add connected address to the interface. */
- listnode_add(ifp->connected, ifc);
+ if_connected_add_tail(ifp->connected, ifc);
return ifc;
}
struct connected *connected_get_linklocal(struct interface *ifp)
{
- struct listnode *n;
struct connected *c = NULL;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (c->address->family == AF_INET6
&& IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
break;
@@ -1340,14 +1319,14 @@ static void cli_show_interface(struct vty *vty, const struct lyd_node *dnode,
char ifname[XPATH_MAXLEN];
char vrfname[XPATH_MAXLEN];
- netns_ifname_split(yang_dnode_get_string(dnode, "./name"),
+ netns_ifname_split(yang_dnode_get_string(dnode, "name"),
ifname, vrfname);
vty_out(vty, "interface %s", ifname);
if (!strmatch(vrfname, VRF_DEFAULT_NAME))
vty_out(vty, " vrf %s", vrfname);
} else {
- const char *ifname = yang_dnode_get_string(dnode, "./name");
+ const char *ifname = yang_dnode_get_string(dnode, "name");
vty_out(vty, "interface %s", ifname);
}
@@ -1361,6 +1340,15 @@ static void cli_show_interface_end(struct vty *vty,
vty_out(vty, "exit\n");
}
+static int cli_cmp_interface(const struct lyd_node *dnode1,
+ const struct lyd_node *dnode2)
+{
+ const char *ifname1 = yang_dnode_get_string(dnode1, "name");
+ const char *ifname2 = yang_dnode_get_string(dnode2, "name");
+
+ return if_cmp_name_func(ifname1, ifname2);
+}
+
void if_vty_config_start(struct vty *vty, struct interface *ifp)
{
vty_frame(vty, "!\n");
@@ -1477,17 +1465,6 @@ void if_cmd_init_default(void)
if_cmd_init(if_nb_config_write);
}
-void if_zapi_callbacks(int (*create)(struct interface *ifp),
- int (*up)(struct interface *ifp),
- int (*down)(struct interface *ifp),
- int (*destroy)(struct interface *ifp))
-{
- ifp_master.create_hook = create;
- ifp_master.up_hook = up;
- ifp_master.down_hook = down;
- ifp_master.destroy_hook = destroy;
-}
-
/* ------- Northbound callbacks ------- */
/*
@@ -1498,7 +1475,7 @@ static int lib_interface_create(struct nb_cb_create_args *args)
const char *ifname;
struct interface *ifp;
- ifname = yang_dnode_get_string(args->dnode, "./name");
+ ifname = yang_dnode_get_string(args->dnode, "name");
switch (args->event) {
case NB_EV_VALIDATE:
@@ -1709,7 +1686,7 @@ lib_interface_state_mtu_get_elem(struct nb_cb_get_elem_args *args)
{
const struct interface *ifp = args->list_entry;
- return yang_data_new_uint16(args->xpath, ifp->mtu);
+ return yang_data_new_uint32(args->xpath, ifp->mtu);
}
/*
@@ -1780,6 +1757,8 @@ lib_interface_state_phy_address_get_elem(struct nb_cb_get_elem_args *args)
}
/* clang-format off */
+
+/* cli_show callbacks are kept here for daemons not yet converted to mgmtd */
const struct frr_yang_module_info frr_interface_info = {
.name = "frr-interface",
.nodes = {
@@ -1790,6 +1769,7 @@ const struct frr_yang_module_info frr_interface_info = {
.destroy = lib_interface_destroy,
.cli_show = cli_show_interface,
.cli_show_end = cli_show_interface_end,
+ .cli_cmp = cli_cmp_interface,
.get_next = lib_interface_get_next,
.get_keys = lib_interface_get_keys,
.lookup_entry = lib_interface_lookup_entry,
@@ -1862,3 +1842,27 @@ const struct frr_yang_module_info frr_interface_info = {
},
}
};
+
+const struct frr_yang_module_info frr_interface_cli_info = {
+ .name = "frr-interface",
+ .ignore_cfg_cbs = true,
+ .nodes = {
+ {
+ .xpath = "/frr-interface:lib/interface",
+ .cbs = {
+ .cli_show = cli_show_interface,
+ .cli_show_end = cli_show_interface_end,
+ .cli_cmp = cli_cmp_interface,
+ },
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/description",
+ .cbs = {
+ .cli_show = cli_show_interface_desc,
+ },
+ },
+ {
+ .xpath = NULL,
+ },
+ }
+};