diff options
Diffstat (limited to '')
-rw-r--r-- | lib/if.c | 140 |
1 files changed, 72 insertions, 68 deletions
@@ -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, + }, + } +}; |