diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/if.c | 6 | ||||
| -rw-r--r-- | lib/log.c | 10 | ||||
| -rw-r--r-- | lib/nexthop_group.c | 100 | ||||
| -rw-r--r-- | lib/nexthop_group.h | 2 | ||||
| -rw-r--r-- | lib/northbound.c | 94 | ||||
| -rw-r--r-- | lib/privs.c | 41 | ||||
| -rw-r--r-- | lib/vrf.c | 6 | ||||
| -rw-r--r-- | lib/vrf.h | 5 | ||||
| -rw-r--r-- | lib/zclient.c | 18 |
9 files changed, 164 insertions, 118 deletions
@@ -396,6 +396,7 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id) struct interface *ifp; switch (vrf_get_backend()) { + case VRF_BACKEND_UNKNOWN: case VRF_BACKEND_NETNS: ifp = if_lookup_by_name(name, vrf_id); if (ifp) @@ -1279,6 +1280,11 @@ static int lib_interface_create(enum nb_event event, vrf->name); return NB_ERR_VALIDATION; } + + /* if VRF is netns or not yet known - init for instance + * then assumption is that passed config is exact + * then the user intent was not to use an other iface + */ if (vrf_get_backend() == VRF_BACKEND_VRF_LITE) { ifp = if_lookup_by_name_all_vrf(ifname); if (ifp && ifp->vrf_id != vrf->vrf_id) { @@ -991,6 +991,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_ROUTER_ID_DELETE), DESC_ENTRY(ZEBRA_ROUTER_ID_UPDATE), DESC_ENTRY(ZEBRA_HELLO), + DESC_ENTRY(ZEBRA_CAPABILITIES), DESC_ENTRY(ZEBRA_NEXTHOP_REGISTER), DESC_ENTRY(ZEBRA_NEXTHOP_UNREGISTER), DESC_ENTRY(ZEBRA_NEXTHOP_UPDATE), @@ -1012,6 +1013,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_VRF_LABEL), DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE), DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER), + DESC_ENTRY(ZEBRA_BFD_CLIENT_DEREGISTER), DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV), DESC_ENTRY(ZEBRA_INTERFACE_DISABLE_RADV), DESC_ENTRY(ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB), @@ -1023,6 +1025,9 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT_ASYNC), DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK), DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK), + DESC_ENTRY(ZEBRA_FEC_REGISTER), + DESC_ENTRY(ZEBRA_FEC_UNREGISTER), + DESC_ENTRY(ZEBRA_FEC_UPDATE), DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI), DESC_ENTRY(ZEBRA_ADVERTISE_DEFAULT_GW), DESC_ENTRY(ZEBRA_ADVERTISE_SVI_MACIP), @@ -1057,6 +1062,11 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_IPSET_DESTROY), DESC_ENTRY(ZEBRA_IPSET_ENTRY_ADD), DESC_ENTRY(ZEBRA_IPSET_ENTRY_DELETE), + DESC_ENTRY(ZEBRA_IPSET_NOTIFY_OWNER), + DESC_ENTRY(ZEBRA_IPSET_ENTRY_NOTIFY_OWNER), + DESC_ENTRY(ZEBRA_IPTABLE_ADD), + DESC_ENTRY(ZEBRA_IPTABLE_DELETE), + DESC_ENTRY(ZEBRA_IPTABLE_NOTIFY_OWNER), DESC_ENTRY(ZEBRA_VXLAN_FLOOD_CONTROL), }; #undef DESC_ENTRY diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index f940418d83..27ab04279c 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -188,11 +188,25 @@ static int nhgc_cmp_helper(const char *a, const char *b) return strcmp(a, b); } +static int nhgc_addr_cmp_helper(const union sockunion *a, const union sockunion *b) +{ + if (!a && !b) + return 0; + + if (a && !b) + return -1; + + if (!a && b) + return 1; + + return sockunion_cmp(a, b); +} + static int nhgl_cmp(struct nexthop_hold *nh1, struct nexthop_hold *nh2) { int ret; - ret = sockunion_cmp(&nh1->addr, &nh2->addr); + ret = nhgc_addr_cmp_helper(nh1->addr, nh2->addr); if (ret) return ret; @@ -209,6 +223,9 @@ static void nhgl_delete(struct nexthop_hold *nh) XFREE(MTYPE_TMP, nh->nhvrf_name); + if (nh->addr) + sockunion_free(nh->addr); + XFREE(MTYPE_TMP, nh); } @@ -292,8 +309,8 @@ static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc, nh->nhvrf_name = XSTRDUP(MTYPE_TMP, nhvrf_name); if (intf) nh->intf = XSTRDUP(MTYPE_TMP, intf); - - nh->addr = *addr; + if (addr) + nh->addr = sockunion_dup(addr); listnode_add_sort(nhgc->nhg_list, nh); } @@ -308,7 +325,7 @@ static void nexthop_group_unsave_nhop(struct nexthop_group_cmd *nhgc, for (ALL_LIST_ELEMENTS_RO(nhgc->nhg_list, node, nh)) { if (nhgc_cmp_helper(nhvrf_name, nh->nhvrf_name) == 0 && - sockunion_cmp(addr, &nh->addr) == 0 && + nhgc_addr_cmp_helper(addr, nh->addr) == 0 && nhgc_cmp_helper(intf, nh->intf) == 0) break; } @@ -320,13 +337,7 @@ static void nexthop_group_unsave_nhop(struct nexthop_group_cmd *nhgc, return; list_delete_node(nhgc->nhg_list, node); - - if (nh->nhvrf_name) - XFREE(MTYPE_TMP, nh->nhvrf_name); - if (nh->intf) - XFREE(MTYPE_TMP, nh->intf); - - XFREE(MTYPE_TMP, nh); + nhgl_delete(nh); } static bool nexthop_group_parse_nexthop(struct nexthop *nhop, @@ -347,36 +358,45 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, nhop->vrf_id = vrf->vrf_id; - if (addr->sa.sa_family == AF_INET) { - nhop->gate.ipv4.s_addr = addr->sin.sin_addr.s_addr; - if (intf) { - nhop->type = NEXTHOP_TYPE_IPV4_IFINDEX; - nhop->ifindex = ifname2ifindex(intf, vrf->vrf_id); - if (nhop->ifindex == IFINDEX_INTERNAL) - return false; - } else - nhop->type = NEXTHOP_TYPE_IPV4; - } else { - memcpy(&nhop->gate.ipv6, &addr->sin6.sin6_addr, 16); - if (intf) { - nhop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - nhop->ifindex = ifname2ifindex(intf, vrf->vrf_id); - if (nhop->ifindex == IFINDEX_INTERNAL) - return false; - } else - nhop->type = NEXTHOP_TYPE_IPV6; + if (intf) { + nhop->ifindex = ifname2ifindex(intf, vrf->vrf_id); + if (nhop->ifindex == IFINDEX_INTERNAL) + return false; } + if (addr) { + if (addr->sa.sa_family == AF_INET) { + nhop->gate.ipv4.s_addr = addr->sin.sin_addr.s_addr; + if (intf) + nhop->type = NEXTHOP_TYPE_IPV4_IFINDEX; + else + nhop->type = NEXTHOP_TYPE_IPV4; + } else { + nhop->gate.ipv6 = addr->sin6.sin6_addr; + if (intf) + nhop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + else + nhop->type = NEXTHOP_TYPE_IPV6; + } + } else + nhop->type = NEXTHOP_TYPE_IFINDEX; + return true; } DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, - "[no] nexthop <A.B.C.D|X:X::X:X>$addr [INTERFACE]$intf [nexthop-vrf NAME$name]", + "[no] nexthop\ + <\ + <A.B.C.D|X:X::X:X>$addr [INTERFACE$intf]\ + |INTERFACE$intf\ + >\ + [nexthop-vrf NAME$name]", NO_STR "Specify one of the nexthops in this ECMP group\n" "v4 Address\n" "v6 Address\n" "Interface to use\n" + "Interface to use\n" "If the nexthop is in a different vrf tell us\n" "The nexthop-vrf Name\n") { @@ -385,13 +405,6 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, struct nexthop *nh; bool legal; - /* - * This is impossible to happen as that the cli parser refuses - * to let you get here without an addr, but the SA system - * does not understand this intricacy - */ - assert(addr); - legal = nexthop_group_parse_nexthop(&nhop, addr, intf, name); if (nhop.type == NEXTHOP_TYPE_IPV6 @@ -480,9 +493,10 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty, { char buf[100]; - vty_out(vty, "nexthop "); + vty_out(vty, "nexthop"); - vty_out(vty, "%s", sockunion2str(&nh->addr, buf, sizeof(buf))); + if (nh->addr) + vty_out(vty, " %s", sockunion2str(nh->addr, buf, sizeof(buf))); if (nh->intf) vty_out(vty, " %s", nh->intf); @@ -504,7 +518,7 @@ static int nexthop_group_write(struct vty *vty) vty_out(vty, "nexthop-group %s\n", nhgc->name); for (ALL_LIST_ELEMENTS_RO(nhgc->nhg_list, node, nh)) { - vty_out(vty, " "); + vty_out(vty, " "); nexthop_group_write_nexthop_internal(vty, nh); } @@ -526,7 +540,7 @@ void nexthop_group_enable_vrf(struct vrf *vrf) struct nexthop nhop; struct nexthop *nh; - if (!nexthop_group_parse_nexthop(&nhop, &nhh->addr, + if (!nexthop_group_parse_nexthop(&nhop, nhh->addr, nhh->intf, nhh->nhvrf_name)) continue; @@ -562,7 +576,7 @@ void nexthop_group_disable_vrf(struct vrf *vrf) struct nexthop nhop; struct nexthop *nh; - if (!nexthop_group_parse_nexthop(&nhop, &nhh->addr, + if (!nexthop_group_parse_nexthop(&nhop, nhh->addr, nhh->intf, nhh->nhvrf_name)) continue; @@ -600,7 +614,7 @@ void nexthop_group_interface_state_change(struct interface *ifp, struct nexthop nhop; if (!nexthop_group_parse_nexthop( - &nhop, &nhh->addr, nhh->intf, + &nhop, nhh->addr, nhh->intf, nhh->nhvrf_name)) continue; diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index b14cbb5b5c..c6e290eeea 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -68,7 +68,7 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh, struct nexthop_hold { char *nhvrf_name; - union sockunion addr; + union sockunion *addr; char *intf; }; diff --git a/lib/northbound.c b/lib/northbound.c index 15139aa8d0..edf7e0eca6 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -348,39 +348,58 @@ static void nb_config_diff_del_changes(struct nb_config_cbs *changes) * configurations. Given a new subtree, calculate all new YANG data nodes, * excluding default leafs and leaf-lists. This is a recursive function. */ -static void nb_config_diff_new_subtree(const struct lyd_node *dnode, - struct nb_config_cbs *changes) +static void nb_config_diff_created(const struct lyd_node *dnode, + struct nb_config_cbs *changes) { + enum nb_operation operation; struct lyd_node *child; - LY_TREE_FOR (dnode->child, child) { - enum nb_operation operation; + switch (dnode->schema->nodetype) { + case LYS_LEAF: + case LYS_LEAFLIST: + if (lyd_wd_default((struct lyd_node_leaf_list *)dnode)) + break; - switch (child->schema->nodetype) { - case LYS_LEAF: - case LYS_LEAFLIST: - if (lyd_wd_default((struct lyd_node_leaf_list *)child)) - break; + if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) + operation = NB_OP_CREATE; + else if (nb_operation_is_valid(NB_OP_MODIFY, dnode->schema)) + operation = NB_OP_MODIFY; + else + return; - if (nb_operation_is_valid(NB_OP_CREATE, child->schema)) - operation = NB_OP_CREATE; - else if (nb_operation_is_valid(NB_OP_MODIFY, - child->schema)) - operation = NB_OP_MODIFY; - else - continue; + nb_config_diff_add_change(changes, operation, dnode); + break; + case LYS_CONTAINER: + case LYS_LIST: + if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) + nb_config_diff_add_change(changes, NB_OP_CREATE, dnode); - nb_config_diff_add_change(changes, operation, child); - break; - case LYS_CONTAINER: - case LYS_LIST: - if (nb_operation_is_valid(NB_OP_CREATE, child->schema)) - nb_config_diff_add_change(changes, NB_OP_CREATE, - child); - nb_config_diff_new_subtree(child, changes); - break; - default: - break; + /* Process child nodes recursively. */ + LY_TREE_FOR (dnode->child, child) { + nb_config_diff_created(child, changes); + } + break; + default: + break; + } +} + +static void nb_config_diff_deleted(const struct lyd_node *dnode, + struct nb_config_cbs *changes) +{ + if (nb_operation_is_valid(NB_OP_DESTROY, dnode->schema)) + nb_config_diff_add_change(changes, NB_OP_DESTROY, dnode); + else if (CHECK_FLAG(dnode->schema->nodetype, LYS_CONTAINER)) { + struct lyd_node *child; + + /* + * Non-presence containers need special handling since they + * don't have "destroy" callbacks. In this case, what we need to + * do is to call the "destroy" callbacks of their child nodes + * when applicable (i.e. optional nodes). + */ + LY_TREE_FOR (dnode->child, child) { + nb_config_diff_deleted(child, changes); } } } @@ -399,42 +418,27 @@ static void nb_config_diff(const struct nb_config *config1, for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) { LYD_DIFFTYPE type; struct lyd_node *dnode; - enum nb_operation operation; type = diff->type[i]; switch (type) { case LYD_DIFF_CREATED: dnode = diff->second[i]; - - if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) - operation = NB_OP_CREATE; - else if (nb_operation_is_valid(NB_OP_MODIFY, - dnode->schema)) - operation = NB_OP_MODIFY; - else - continue; + nb_config_diff_created(dnode, changes); break; case LYD_DIFF_DELETED: dnode = diff->first[i]; - operation = NB_OP_DESTROY; + nb_config_diff_deleted(dnode, changes); break; case LYD_DIFF_CHANGED: dnode = diff->second[i]; - operation = NB_OP_MODIFY; + nb_config_diff_add_change(changes, NB_OP_MODIFY, dnode); break; case LYD_DIFF_MOVEDAFTER1: case LYD_DIFF_MOVEDAFTER2: default: continue; } - - nb_config_diff_add_change(changes, operation, dnode); - - if (type == LYD_DIFF_CREATED - && CHECK_FLAG(dnode->schema->nodetype, - LYS_CONTAINER | LYS_LIST)) - nb_config_diff_new_subtree(dnode, changes); } lyd_free_diff(diff); diff --git a/lib/privs.c b/lib/privs.c index 3ce8e0d57a..59f24afe4a 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -708,19 +708,19 @@ struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs, /* If we're already elevated, just return */ pthread_mutex_lock(&(privs->mutex)); - if (++privs->refcount > 1) { - pthread_mutex_unlock(&(privs->mutex)); - return privs; + { + if (++(privs->refcount) == 1) { + errno = 0; + if (privs->change(ZPRIVS_RAISE)) { + zlog_err("%s: Failed to raise privileges (%s)", + funcname, safe_strerror(errno)); + } + errno = save_errno; + privs->raised_in_funcname = funcname; + } } pthread_mutex_unlock(&(privs->mutex)); - errno = 0; - if (privs->change(ZPRIVS_RAISE)) { - zlog_err("%s: Failed to raise privileges (%s)", - funcname, safe_strerror(errno)); - } - errno = save_errno; - privs->raised_in_funcname = funcname; return privs; } @@ -733,19 +733,20 @@ void _zprivs_lower(struct zebra_privs_t **privs) /* Don't lower privs if there's another caller */ pthread_mutex_lock(&(*privs)->mutex); - if (--((*privs)->refcount) > 0) { - pthread_mutex_unlock(&(*privs)->mutex); - return; + { + if (--((*privs)->refcount) == 0) { + errno = 0; + if ((*privs)->change(ZPRIVS_LOWER)) { + zlog_err("%s: Failed to lower privileges (%s)", + (*privs)->raised_in_funcname, + safe_strerror(errno)); + } + errno = save_errno; + (*privs)->raised_in_funcname = NULL; + } } pthread_mutex_unlock(&(*privs)->mutex); - errno = 0; - if ((*privs)->change(ZPRIVS_LOWER)) { - zlog_err("%s: Failed to lower privileges (%s)", - (*privs)->raised_in_funcname, safe_strerror(errno)); - } - errno = save_errno; - (*privs)->raised_in_funcname = NULL; *privs = NULL; } @@ -56,6 +56,7 @@ struct vrf_id_head vrfs_by_id = RB_INITIALIZER(&vrfs_by_id); struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name); static int vrf_backend; +static int vrf_backend_configured; static struct zebra_privs_t *vrf_daemon_privs; static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL; @@ -613,12 +614,15 @@ int vrf_is_backend_netns(void) int vrf_get_backend(void) { + if (!vrf_backend_configured) + return VRF_BACKEND_UNKNOWN; return vrf_backend; } void vrf_configure_backend(int vrf_backend_netns) { vrf_backend = vrf_backend_netns; + vrf_backend_configured = 1; } int vrf_handler_create(struct vty *vty, const char *vrfname, @@ -662,7 +666,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, "VRF %u is already configured with VRF %s\n", vrf->vrf_id, vrf->name); else - zlog_info("VRF %u is already configured with VRF %s\n", + zlog_info("VRF %u is already configured with VRF %s", vrf->vrf_id, vrf->name); return CMD_WARNING_CONFIG_FAILED; } @@ -101,8 +101,9 @@ RB_PROTOTYPE(vrf_name_head, vrf, name_entry, vrf_name_compare) DECLARE_QOBJ_TYPE(vrf) /* Allow VRF with netns as backend */ -#define VRF_BACKEND_VRF_LITE 0 -#define VRF_BACKEND_NETNS 1 +#define VRF_BACKEND_VRF_LITE 0 +#define VRF_BACKEND_NETNS 1 +#define VRF_BACKEND_UNKNOWN 2 extern struct vrf_id_head vrfs_by_id; extern struct vrf_name_head vrfs_by_name; diff --git a/lib/zclient.c b/lib/zclient.c index 9db1dd74f2..3e26cd9e6c 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -414,6 +414,9 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) /* We need router-id information. */ zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id); + /* We need interface information. */ + zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id); + /* Set unwanted redistribute route. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) vrf_bitmap_set(zclient->redist[afi][zclient->redist_default], @@ -478,6 +481,8 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id) /* We need router-id information. */ zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id); + zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id); + /* Set unwanted redistribute route. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default], @@ -629,7 +634,7 @@ void zclient_init(struct zclient *zclient, int redist_default, } if (zclient_debug) - zlog_debug("zclient_start is called"); + zlog_debug("scheduling zclient connection"); zclient_event(ZCLIENT_SCHEDULE, zclient); } @@ -2504,8 +2509,9 @@ static int zclient_read(struct thread *thread) length -= ZEBRA_HEADER_SIZE; if (zclient_debug) - zlog_debug("zclient 0x%p command 0x%x VRF %u\n", - (void *)zclient, command, vrf_id); + zlog_debug("zclient 0x%p command %s VRF %u", + (void *)zclient, zserv_command_string(command), + vrf_id); switch (command) { case ZEBRA_CAPABILITIES: @@ -2574,14 +2580,14 @@ static int zclient_read(struct thread *thread) break; case ZEBRA_NEXTHOP_UPDATE: if (zclient_debug) - zlog_debug("zclient rcvd nexthop update\n"); + zlog_debug("zclient rcvd nexthop update"); if (zclient->nexthop_update) (*zclient->nexthop_update)(command, zclient, length, vrf_id); break; case ZEBRA_IMPORT_CHECK_UPDATE: if (zclient_debug) - zlog_debug("zclient rcvd import check update\n"); + zlog_debug("zclient rcvd import check update"); if (zclient->import_check_update) (*zclient->import_check_update)(command, zclient, length, vrf_id); @@ -2608,7 +2614,7 @@ static int zclient_read(struct thread *thread) break; case ZEBRA_FEC_UPDATE: if (zclient_debug) - zlog_debug("zclient rcvd fec update\n"); + zlog_debug("zclient rcvd fec update"); if (zclient->fec_update) (*zclient->fec_update)(command, zclient, length); break; |
