diff options
Diffstat (limited to 'staticd/static_nb_config.c')
| -rw-r--r-- | staticd/static_nb_config.c | 305 |
1 files changed, 280 insertions, 25 deletions
diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c index 01cd281d9c..7de5f0474a 100644 --- a/staticd/static_nb_config.c +++ b/staticd/static_nb_config.c @@ -18,6 +18,7 @@ #include "static_vrf.h" #include "static_routes.h" #include "static_nb.h" +#include "static_zebra.h" static int static_path_list_create(struct nb_cb_create_args *args) @@ -33,8 +34,8 @@ static int static_path_list_create(struct nb_cb_create_args *args) case NB_EV_VALIDATE: vrf_dnode = yang_dnode_get_parent(args->dnode, "control-plane-protocol"); - vrf = yang_dnode_get_string(vrf_dnode, "./vrf"); - table_id = yang_dnode_get_uint32(args->dnode, "./table-id"); + vrf = yang_dnode_get_string(vrf_dnode, "vrf"); + table_id = yang_dnode_get_uint32(args->dnode, "table-id"); /* * TableId is not applicable for VRF. Consider the case of @@ -55,8 +56,8 @@ static int static_path_list_create(struct nb_cb_create_args *args) break; case NB_EV_APPLY: rn = nb_running_get_entry(args->dnode, NULL, true); - distance = yang_dnode_get_uint8(args->dnode, "./distance"); - table_id = yang_dnode_get_uint32(args->dnode, "./table-id"); + distance = yang_dnode_get_uint8(args->dnode, "distance"); + table_id = yang_dnode_get_uint32(args->dnode, "table-id"); pn = static_add_path(rn, table_id, distance); nb_running_set_entry(args->dnode, pn); } @@ -111,7 +112,7 @@ static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg) struct nexthop_iter *iter = arg; enum static_nh_type nh_type; - nh_type = yang_dnode_get_enum(dnode, "./nh-type"); + nh_type = yang_dnode_get_enum(dnode, "nh-type"); if (nh_type == STATIC_BLACKHOLE) iter->blackhole = true; @@ -134,7 +135,7 @@ static bool static_nexthop_create(struct nb_cb_create_args *args) switch (args->event) { case NB_EV_VALIDATE: - ifname = yang_dnode_get_string(args->dnode, "./interface"); + ifname = yang_dnode_get_string(args->dnode, "interface"); if (ifname != NULL) { if (strcasecmp(ifname, "Null0") == 0 || strcasecmp(ifname, "reject") == 0 @@ -169,12 +170,15 @@ static bool static_nexthop_create(struct nb_cb_create_args *args) case NB_EV_ABORT: break; case NB_EV_APPLY: - yang_dnode_get_ip(&ipaddr, args->dnode, "./gateway"); - nh_type = yang_dnode_get_enum(args->dnode, "./nh-type"); - ifname = yang_dnode_get_string(args->dnode, "./interface"); - nh_vrf = yang_dnode_get_string(args->dnode, "./vrf"); + yang_dnode_get_ip(&ipaddr, args->dnode, "gateway"); + nh_type = yang_dnode_get_enum(args->dnode, "nh-type"); + ifname = yang_dnode_get_string(args->dnode, "interface"); + nh_vrf = yang_dnode_get_string(args->dnode, "vrf"); pn = nb_running_get_entry(args->dnode, NULL, true); + if (strmatch(ifname, "(null)")) + ifname = ""; + if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr)) flog_warn( EC_LIB_NB_CB_CONFIG_VALIDATE, @@ -208,6 +212,98 @@ static bool static_nexthop_destroy(struct nb_cb_destroy_args *args) return NB_OK; } +static int nexthop_srv6_segs_stack_entry_create(struct nb_cb_create_args *args) +{ + struct static_nexthop *nh; + uint32_t pos; + uint8_t index; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + nh = nb_running_get_entry(args->dnode, NULL, true); + pos = yang_get_list_pos(args->dnode); + if (!pos) { + flog_warn(EC_LIB_NB_CB_CONFIG_APPLY, + "libyang returns invalid seg position"); + return NB_ERR; + } + /* Mapping to array = list-index -1 */ + index = pos - 1; + memset(&nh->snh_seg.seg[index], 0, sizeof(struct in6_addr)); + nh->snh_seg.num_segs++; + break; + } + + return NB_OK; +} + +static int nexthop_srv6_segs_stack_entry_destroy(struct nb_cb_destroy_args *args) +{ + struct static_nexthop *nh; + uint32_t pos; + uint8_t index; + int old_num_segs; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + nh = nb_running_get_entry(args->dnode, NULL, true); + pos = yang_get_list_pos(args->dnode); + if (!pos) { + flog_warn(EC_LIB_NB_CB_CONFIG_APPLY, + "libyang returns invalid seg position"); + return NB_ERR; + } + index = pos - 1; + old_num_segs = nh->snh_seg.num_segs; + memset(&nh->snh_seg.seg[index], 0, sizeof(struct in6_addr)); + nh->snh_seg.num_segs--; + + if (old_num_segs != nh->snh_seg.num_segs) + nh->state = STATIC_START; + break; + } + + return NB_OK; +} + +static int static_nexthop_srv6_segs_modify(struct nb_cb_modify_args *args) +{ + struct static_nexthop *nh; + uint32_t pos; + uint8_t index; + struct in6_addr old_seg; + struct in6_addr cli_seg; + + nh = nb_running_get_entry(args->dnode, NULL, true); + pos = yang_get_list_pos(lyd_parent(args->dnode)); + if (!pos) { + flog_warn(EC_LIB_NB_CB_CONFIG_APPLY, + "libyang returns invalid seg position"); + return NB_ERR; + } + /* Mapping to array = list-index -1 */ + index = pos - 1; + + old_seg = nh->snh_seg.seg[index]; + yang_dnode_get_ipv6(&cli_seg, args->dnode, NULL); + + memcpy(&nh->snh_seg.seg[index], &cli_seg, sizeof(struct in6_addr)); + + if (memcmp(&old_seg, &nh->snh_seg.seg[index], + sizeof(struct in6_addr)) != 0) + nh->state = STATIC_START; + + return NB_OK; +} + static int nexthop_mpls_label_stack_entry_create(struct nb_cb_create_args *args) { struct static_nexthop *nh; @@ -419,7 +515,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa const struct lyd_node *mls_dnode; uint32_t count; - mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack"); + mls_dnode = yang_dnode_get(args->dnode, "mpls-label-stack"); count = yang_get_list_elements_count(lyd_child(mls_dnode)); if (count > MPLS_MAX_LABELS) { @@ -436,7 +532,7 @@ int routing_control_plane_protocols_name_validate( { const char *name; - name = yang_dnode_get_string(args->dnode, "./name"); + name = yang_dnode_get_string(args->dnode, "name"); if (!strmatch(name, "staticd")) { snprintf(args->errmsg, args->errmsg_len, "static routing supports only one instance with name staticd"); @@ -444,6 +540,48 @@ int routing_control_plane_protocols_name_validate( } return NB_OK; } + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol + */ +int routing_control_plane_protocols_staticd_create(struct nb_cb_create_args *args) +{ + struct static_vrf *svrf; + const char *vrf; + + vrf = yang_dnode_get_string(args->dnode, "vrf"); + svrf = static_vrf_alloc(vrf); + nb_running_set_entry(args->dnode, svrf); + + return NB_OK; +} + +int routing_control_plane_protocols_staticd_destroy( + struct nb_cb_destroy_args *args) +{ + struct static_vrf *svrf; + struct route_table *stable; + struct route_node *rn; + afi_t afi; + safi_t safi; + + svrf = nb_running_unset_entry(args->dnode); + + FOREACH_AFI_SAFI (afi, safi) { + stable = svrf->stable[afi][safi]; + if (!stable) + continue; + + for (rn = route_top(stable); rn; rn = route_next(rn)) + static_del_route(rn); + } + + static_vrf_free(svrf); + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list @@ -451,8 +589,7 @@ int routing_control_plane_protocols_name_validate( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create( struct nb_cb_create_args *args) { - struct vrf *vrf; - struct static_vrf *s_vrf; + struct static_vrf *svrf; struct route_node *rn; const struct lyd_node *vrf_dnode; struct prefix prefix; @@ -463,15 +600,15 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr switch (args->event) { case NB_EV_VALIDATE: - yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); - afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi"); + yang_dnode_get_prefix(&prefix, args->dnode, "prefix"); + afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); yang_afi_safi_identity2value(afi_safi, &afi, &safi); prefix_afi = family2afi(prefix.family); if (afi != prefix_afi) { flog_warn( EC_LIB_NB_CB_CONFIG_VALIDATE, "route node %s creation failed", - yang_dnode_get_string(args->dnode, "./prefix")); + yang_dnode_get_string(args->dnode, "prefix")); return NB_ERR_VALIDATION; } break; @@ -481,19 +618,18 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr case NB_EV_APPLY: vrf_dnode = yang_dnode_get_parent(args->dnode, "control-plane-protocol"); - vrf = nb_running_get_entry(vrf_dnode, NULL, true); - s_vrf = vrf->info; + svrf = nb_running_get_entry(vrf_dnode, NULL, true); - yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); - afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi"); + yang_dnode_get_prefix(&prefix, args->dnode, "prefix"); + afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); yang_afi_safi_identity2value(afi_safi, &afi, &safi); - rn = static_add_route(afi, safi, &prefix, NULL, s_vrf); - if (vrf->vrf_id == VRF_UNKNOWN) + rn = static_add_route(afi, safi, &prefix, NULL, svrf); + if (!svrf->vrf || svrf->vrf->vrf_id == VRF_UNKNOWN) snprintf( args->errmsg, args->errmsg_len, "Static Route to %s not installed currently because dependent config not fully available", - yang_dnode_get_string(args->dnode, "./prefix")); + yang_dnode_get_string(args->dnode, "prefix")); nb_running_set_entry(args->dnode, rn); break; } @@ -619,6 +755,60 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srv6-segs-stack/entry + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_create( + struct nb_cb_create_args *args) +{ + return nexthop_srv6_segs_stack_entry_create(args); +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_destroy( + struct nb_cb_destroy_args *args) +{ + return nexthop_srv6_segs_stack_entry_destroy(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srv6-segs-stack/entry/seg + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_seg_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (static_nexthop_srv6_segs_modify(args) != NB_OK) + return NB_ERR; + break; + } + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_seg_destroy( + struct nb_cb_destroy_args *args) +{ + /* + * No operation is required in this call back. + * nexthop_srv6_segs_stack_entry_destroy() will take care + * to reset the seg vaue. + */ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry */ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create( @@ -790,6 +980,17 @@ int route_next_hop_bfd_source_destroy(struct nb_cb_destroy_args *args) sn = nb_running_get_entry(args->dnode, NULL, true); static_next_hop_bfd_auto_source(sn); + + /* NHT information are needed by BFD to automatically find the source + * + * Force zebra to resend the information to BFD by unregistering and + * registering again NHT. The (...)/frr-nexthops/nexthop northbound + * apply_finish function will trigger a call to static_install_nexthop() + * that does a call to static_zebra_nht_register(nh, true); + * static_zebra_nht_register(sn, false); + */ + static_zebra_nht_register(sn, false); + return NB_OK; } @@ -866,7 +1067,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr rn = nb_running_get_entry(args->dnode, NULL, true); info = route_table_get_info(rn->table); s_vrf = info->svrf; - yang_dnode_get_ipv6p(&src_prefix, args->dnode, "./src-prefix"); + yang_dnode_get_ipv6p(&src_prefix, args->dnode, "src-prefix"); afi = family2afi(src_prefix.family); src_rn = static_add_route(afi, safi, &rn->p, &src_prefix, s_vrf); @@ -997,6 +1198,60 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srv6-segs-stack/entry + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_create( + struct nb_cb_create_args *args) +{ + return nexthop_srv6_segs_stack_entry_create(args); +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_destroy( + struct nb_cb_destroy_args *args) +{ + return nexthop_srv6_segs_stack_entry_destroy(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srv6-segs-stack/entry/seg + */ +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_seg_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (static_nexthop_srv6_segs_modify(args) != NB_OK) + return NB_ERR; + break; + } + return NB_OK; +} + +int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_seg_destroy( + struct nb_cb_destroy_args *args) +{ + /* + * No operation is required in this call back. + * nexthop_mpls_seg_stack_entry_destroy() will take care + * to reset the seg vaue. + */ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry */ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create( |
