diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c index 3247a0372cb5..7203c8ac8ed7 100644 --- a/lib/srcdest_table.c +++ b/lib/srcdest_table.c @@ -309,13 +309,3 @@ static ssize_t printfrr_rn(struct fbuf *buf, struct printfrr_eargs *ea, cbuf, sizeof(cbuf)); return bputs(buf, cbuf); } - -struct route_table *srcdest_srcnode_table(struct route_node *rn) -{ - if (rnode_is_dstnode(rn)) { - struct srcdest_rnode *srn = srcdest_rnode_from_rnode(rn); - - return srn->src_table; - } - return NULL; -} diff --git a/lib/srcdest_table.h b/lib/srcdest_table.h index ff97f9b73524..a699d4a11b22 100644 --- a/lib/srcdest_table.h +++ b/lib/srcdest_table.h @@ -87,8 +87,6 @@ static inline void *srcdest_rnode_table_info(struct route_node *rn) return route_table_get_info(srcdest_rnode_table(rn)); } -extern struct route_table *srcdest_srcnode_table(struct route_node *rn); - #ifdef __cplusplus } #endif diff --git a/lib/zclient.c b/lib/zclient.c index 9f6542eb31e2..d8c75c902972 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2123,6 +2123,15 @@ bool zapi_route_notify_decode(struct stream *s, struct prefix *p, uint32_t *tableid, enum zapi_route_notify_owner *note, afi_t *afi, safi_t *safi) +{ + struct prefix dummy; + + return zapi_route_notify_decode_srcdest(s, p, &dummy, tableid, note, afi, safi); +} + +bool zapi_route_notify_decode_srcdest(struct stream *s, struct prefix *p, struct prefix *src_p, + uint32_t *tableid, enum zapi_route_notify_owner *note, + afi_t *afi, safi_t *safi) { uint32_t t; afi_t afi_val; @@ -2133,6 +2142,9 @@ bool zapi_route_notify_decode(struct stream *s, struct prefix *p, STREAM_GETC(s, p->family); STREAM_GETC(s, p->prefixlen); STREAM_GET(&p->u.prefix, s, prefix_blen(p)); + src_p->family = p->family; + STREAM_GETC(s, src_p->prefixlen); + STREAM_GET(&src_p->u.prefix, s, prefix_blen(src_p)); STREAM_GETL(s, t); STREAM_GETC(s, afi_val); STREAM_GETC(s, safi_val); diff --git a/lib/zclient.h b/lib/zclient.h index f3657822b841..afd84acce27d 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -1168,6 +1168,9 @@ bool zapi_route_notify_decode(struct stream *s, struct prefix *p, uint32_t *tableid, enum zapi_route_notify_owner *note, afi_t *afi, safi_t *safi); +bool zapi_route_notify_decode_srcdest(struct stream *s, struct prefix *p, struct prefix *src_p, + uint32_t *tableid, enum zapi_route_notify_owner *note, + afi_t *afi, safi_t *safi); bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno, uint32_t *priority, uint32_t *unique, char *ifname, enum zapi_rule_notify_owner *note); diff --git a/staticd/static_nb.c b/staticd/static_nb.c index 356324126a44..ef363bfe7e62 100644 --- a/staticd/static_nb.c +++ b/staticd/static_nb.c @@ -134,96 +134,6 @@ const struct frr_yang_module_info frr_staticd_info = { .destroy = route_next_hop_bfd_profile_destroy, } }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list", - .cbs = { - .create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list", - .cbs = { - .create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/tag", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop", - .cbs = { - .apply_finish = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish, - .create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy, - .pre_validate = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy, - } - }, - { - .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", - .cbs = { - .create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_create, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_destroy, - } - }, - { - .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", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_seg_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_srv6_segs_stack_entry_seg_destroy, - } - }, - { - .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", - .cbs = { - .create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy, - } - }, - { - .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/label", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy, - } - }, - { - .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/ttl", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy, - } - }, - { - .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/traffic-class", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy, - } - }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing/srv6/static-sids/sid", .cbs = { diff --git a/staticd/static_nb.h b/staticd/static_nb.h index d11bf5363bd5..aa11f340212b 100644 --- a/staticd/static_nb.h +++ b/staticd/static_nb.h @@ -72,52 +72,6 @@ int route_next_hop_bfd_source_destroy(struct nb_cb_destroy_args *args); int route_next_hop_bfd_profile_modify(struct nb_cb_modify_args *args); int route_next_hop_bfd_profile_destroy(struct nb_cb_destroy_args *args); int route_next_hop_bfd_multi_hop_modify(struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create( - struct nb_cb_create_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy( - struct nb_cb_destroy_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create( - struct nb_cb_create_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy( - struct nb_cb_destroy_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create( - struct nb_cb_create_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy( - struct nb_cb_destroy_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy( - struct nb_cb_destroy_args *args); -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); -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); -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); -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); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create( - struct nb_cb_create_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy( - struct nb_cb_destroy_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy( - struct nb_cb_destroy_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy( - struct nb_cb_destroy_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify( - struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy( - struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_create( struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_destroy( @@ -151,8 +105,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_segment_routi void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish( struct nb_cb_apply_finish_args *args); -void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish( - struct nb_cb_apply_finish_args *args); void routing_control_plane_protocols_control_plane_protocol_staticd_segment_routing_srv6_local_sids_sid_apply_finish( struct nb_cb_apply_finish_args *args); @@ -169,16 +121,16 @@ int routing_control_plane_protocols_name_validate( /* xpath macros */ /* route-list */ -#define FRR_STATIC_ROUTE_INFO_KEY_XPATH \ - "/frr-routing:routing/control-plane-protocols/" \ - "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ - "frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \ +#define FRR_STATIC_ROUTE_INFO_KEY_XPATH \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ + "frr-staticd:staticd/route-list[prefix='%s'][src-prefix='%s'][afi-safi='%s']/" \ "path-list[table-id='%u'][distance='%u']" -#define FRR_STATIC_ROUTE_INFO_KEY_NO_DISTANCE_XPATH \ - "/frr-routing:routing/control-plane-protocols/" \ - "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ - "frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \ +#define FRR_STATIC_ROUTE_INFO_KEY_NO_DISTANCE_XPATH \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ + "frr-staticd:staticd/route-list[prefix='%s'][src-prefix='%s'][afi-safi='%s']/" \ "path-list[table-id='%u']" @@ -203,19 +155,6 @@ int routing_control_plane_protocols_name_validate( #define FRR_STATIC_ROUTE_NH_SRV6_KEY_SEG_XPATH "/entry[id='%u']/seg" -/* route-list/srclist */ -#define FRR_S_ROUTE_SRC_INFO_KEY_XPATH \ - "/frr-routing:routing/control-plane-protocols/" \ - "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ - "frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \ - "src-list[src-prefix='%s']/path-list[table-id='%u'][distance='%u']" - -#define FRR_S_ROUTE_SRC_INFO_KEY_NO_DISTANCE_XPATH \ - "/frr-routing:routing/control-plane-protocols/" \ - "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ - "frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \ - "src-list[src-prefix='%s']/path-list[table-id='%u']" - /* route-list/frr-nexthops */ #define FRR_DEL_S_ROUTE_NH_KEY_XPATH \ FRR_STATIC_ROUTE_INFO_KEY_XPATH \ @@ -226,16 +165,6 @@ int routing_control_plane_protocols_name_validate( FRR_STATIC_ROUTE_INFO_KEY_NO_DISTANCE_XPATH \ FRR_STATIC_ROUTE_NH_KEY_XPATH -/* route-list/src/src-list/frr-nexthops*/ -#define FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH \ - FRR_S_ROUTE_SRC_INFO_KEY_XPATH \ - FRR_STATIC_ROUTE_NH_KEY_XPATH - -/* route-list/src/src-list/frr-nexthops*/ -#define FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH \ - FRR_S_ROUTE_SRC_INFO_KEY_NO_DISTANCE_XPATH \ - FRR_STATIC_ROUTE_NH_KEY_XPATH - /* srv6 */ #define FRR_STATIC_SRV6_INFO_KEY_XPATH \ "/frr-routing:routing/control-plane-protocols/" \ diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c index 51de05c2eaa9..e2ab1f2ffefe 100644 --- a/staticd/static_nb_config.c +++ b/staticd/static_nb_config.c @@ -502,16 +502,6 @@ void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_p static_install_nexthop(nh); } -void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish( - struct nb_cb_apply_finish_args *args) -{ - struct static_nexthop *nh; - - nh = nb_running_get_entry(args->dnode, NULL, true); - - static_install_nexthop(nh); -} - int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate( struct nb_cb_pre_validate_args *args) { @@ -576,7 +566,7 @@ int routing_control_plane_protocols_staticd_destroy( if (!stable) continue; - for (rn = route_top(stable); rn; rn = route_next(rn)) + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) static_del_route(rn); } @@ -595,7 +585,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr struct static_vrf *svrf; struct route_node *rn; const struct lyd_node *vrf_dnode; - struct prefix prefix; + struct prefix prefix, src_prefix, *src_p; const char *afi_safi; afi_t prefix_afi; afi_t afi; @@ -604,6 +594,8 @@ 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"); + yang_dnode_get_prefix(&src_prefix, args->dnode, "src-prefix"); + src_p = src_prefix.prefixlen ? &src_prefix : NULL; afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); yang_afi_safi_identity2value(afi_safi, &afi, &safi); prefix_afi = family2afi(prefix.family); @@ -614,6 +606,14 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr yang_dnode_get_string(args->dnode, "prefix")); return NB_ERR_VALIDATION; } + + if (src_p && afi != AFI_IP6) { + flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE, + "invalid use of IPv6 dst-src prefix %s on %s", + yang_dnode_get_string(args->dnode, "src-prefix"), + yang_dnode_get_string(args->dnode, "prefix")); + return NB_ERR_VALIDATION; + } break; case NB_EV_PREPARE: case NB_EV_ABORT: @@ -624,10 +624,12 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr svrf = nb_running_get_entry(vrf_dnode, NULL, true); yang_dnode_get_prefix(&prefix, args->dnode, "prefix"); + yang_dnode_get_prefix(&src_prefix, args->dnode, "src-prefix"); + src_p = src_prefix.prefixlen ? &src_prefix : NULL; 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, svrf); + rn = static_add_route(afi, safi, &prefix, (struct prefix_ipv6 *)src_p, svrf); if (!svrf->vrf || svrf->vrf->vrf_id == VRF_UNKNOWN) snprintf( args->errmsg, args->errmsg_len, @@ -1046,331 +1048,6 @@ int route_next_hop_bfd_profile_destroy(struct nb_cb_destroy_args *args) return NB_OK; } -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create( - struct nb_cb_create_args *args) -{ - struct static_vrf *s_vrf; - struct route_node *rn; - struct route_node *src_rn; - struct prefix_ipv6 src_prefix = {}; - struct stable_info *info; - afi_t afi; - safi_t safi = SAFI_UNICAST; - - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - 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"); - afi = family2afi(src_prefix.family); - src_rn = - static_add_route(afi, safi, &rn->p, &src_prefix, s_vrf); - nb_running_set_entry(args->dnode, src_rn); - break; - } - return NB_OK; -} - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy( - struct nb_cb_destroy_args *args) -{ - struct route_node *src_rn; - - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - src_rn = nb_running_unset_entry(args->dnode); - static_del_route(src_rn); - break; - } - - return NB_OK; -} - -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create( - struct nb_cb_create_args *args) -{ - return static_path_list_create(args); -} - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy( - struct nb_cb_destroy_args *args) -{ - return static_path_list_destroy(args); -} - -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/tag - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify( - struct nb_cb_modify_args *args) -{ - return static_path_list_tag_modify(args); -} - -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create( - struct nb_cb_create_args *args) -{ - return static_nexthop_create(args); -} - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy( - struct nb_cb_destroy_args *args) -{ - return static_nexthop_destroy(args); -} - -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify( - struct nb_cb_modify_args *args) -{ - return static_nexthop_bh_type_modify(args); -} - -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify( - struct nb_cb_modify_args *args) -{ - return static_nexthop_onlink_modify(args); -} - -/* - * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_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_color_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_color_destroy( - struct nb_cb_destroy_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_color_destroy(args) != NB_OK) - return NB_ERR; - 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/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( - struct nb_cb_create_args *args) -{ - return nexthop_mpls_label_stack_entry_create(args); -} - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy( - struct nb_cb_destroy_args *args) -{ - return nexthop_mpls_label_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/mpls-label-stack/entry/label - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_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_mpls_label_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_mpls_label_stack_entry_label_destroy( - struct nb_cb_destroy_args *args) -{ - /* - * No operation is required in this call back. - * nexthop_mpls_label_stack_entry_destroy() will take care - * to reset the label 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/ttl - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify( - struct nb_cb_modify_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - break; - } - - return NB_OK; -} - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy( - struct nb_cb_destroy_args *args) -{ - 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/traffic-class - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify( - struct nb_cb_modify_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - break; - } - - return NB_OK; -} - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy( - struct nb_cb_destroy_args *args) -{ - 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/segment-routing diff --git a/staticd/static_nht.c b/staticd/static_nht.c index 06d27c6f598b..367ee850408f 100644 --- a/staticd/static_nht.c +++ b/staticd/static_nht.c @@ -49,8 +49,8 @@ static void static_nht_update_path(struct static_path *pn, struct prefix *nhp, static_zebra_route_add(pn, true); } -static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp, - uint32_t nh_num, afi_t afi, safi_t safi, +static void static_nht_update_safi(const struct prefix *sp, const struct prefix *ssrc_p, + struct prefix *nhp, uint32_t nh_num, afi_t afi, safi_t safi, struct static_vrf *svrf, vrf_id_t nh_vrf_id) { struct route_table *stable; @@ -63,7 +63,7 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp, return; if (sp) { - rn = srcdest_rnode_lookup(stable, sp, NULL); + rn = srcdest_rnode_lookup(stable, sp, (const struct prefix_ipv6 *)ssrc_p); if (rn && rn->info) { si = static_route_info_from_rnode(rn); frr_each(static_path_list, &si->path_list, pn) { @@ -75,7 +75,7 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp, return; } - for (rn = route_top(stable); rn; rn = route_next(rn)) { + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { si = static_route_info_from_rnode(rn); if (!si) continue; @@ -85,14 +85,13 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp, } } -void static_nht_update(struct prefix *sp, struct prefix *nhp, uint32_t nh_num, - afi_t afi, safi_t safi, vrf_id_t nh_vrf_id) +void static_nht_update(const struct prefix *sp, const struct prefix *ssrc_p, struct prefix *nhp, + uint32_t nh_num, afi_t afi, safi_t safi, vrf_id_t nh_vrf_id) { struct static_vrf *svrf; RB_FOREACH (svrf, svrf_name_head, &svrfs) - static_nht_update_safi(sp, nhp, nh_num, afi, safi, svrf, - nh_vrf_id); + static_nht_update_safi(sp, ssrc_p, nhp, nh_num, afi, safi, svrf, nh_vrf_id); } static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi, @@ -109,7 +108,7 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi, if (!stable) return; - for (rn = route_top(stable); rn; rn = route_next(rn)) { + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { si = static_route_info_from_rnode(rn); if (!si) continue; @@ -150,8 +149,8 @@ void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi, static_nht_reset_start_safi(nhp, afi, safi, svrf, nh_vrf_id); } -static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi, - safi_t safi, struct vrf *vrf, +static void static_nht_mark_state_safi(const struct prefix *sp, const struct prefix *ssrc_p, + afi_t afi, safi_t safi, struct vrf *vrf, enum static_install_states state) { struct static_vrf *svrf; @@ -169,7 +168,7 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi, if (!stable) return; - rn = srcdest_rnode_lookup(stable, sp, NULL); + rn = srcdest_rnode_lookup(stable, sp, (const struct prefix_ipv6 *)ssrc_p); if (!rn) return; si = rn->info; @@ -184,8 +183,8 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi, route_unlock_node(rn); } -void static_nht_mark_state(struct prefix *sp, safi_t safi, vrf_id_t vrf_id, - enum static_install_states state) +void static_nht_mark_state(const struct prefix *sp, const struct prefix *ssrc_p, safi_t safi, + vrf_id_t vrf_id, enum static_install_states state) { struct vrf *vrf; @@ -198,5 +197,5 @@ void static_nht_mark_state(struct prefix *sp, safi_t safi, vrf_id_t vrf_id, if (!vrf || !vrf->info) return; - static_nht_mark_state_safi(sp, afi, safi, vrf, state); + static_nht_mark_state_safi(sp, ssrc_p, afi, safi, vrf, state); } diff --git a/staticd/static_nht.h b/staticd/static_nht.h index 74f4401e49eb..41ff30cd52b9 100644 --- a/staticd/static_nht.h +++ b/staticd/static_nht.h @@ -16,15 +16,14 @@ extern "C" { * us call this function to find the nexthop we are tracking so it * can be installed or removed. * - * sp -> The route we are looking at. If NULL then look at all - * routes. + * sp + ssrc_p -> The route we are looking at. If NULL then look at all routes. * nhp -> The nexthop that is being tracked. * nh_num -> number of valid nexthops. * afi -> The afi we are working in. * vrf_id -> The vrf the nexthop is in. */ -extern void static_nht_update(struct prefix *sp, struct prefix *nhp, - uint32_t nh_num, afi_t afi, safi_t safi, +extern void static_nht_update(const struct prefix *sp, const struct prefix *ssrc_p, + struct prefix *nhp, uint32_t nh_num, afi_t afi, safi_t safi, vrf_id_t vrf_id); /* @@ -35,11 +34,10 @@ extern void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi, vrf_id_t nh_vrf_id); /* - * For the given prefix, sp, mark it as in a particular state + * For the given prefix, sp + ssrc_p, mark it as in a particular state */ -extern void static_nht_mark_state(struct prefix *sp, safi_t safi, - vrf_id_t vrf_id, - enum static_install_states state); +extern void static_nht_mark_state(const struct prefix *sp, const struct prefix *ssrc_p, safi_t safi, + vrf_id_t vrf_id, enum static_install_states state); /* * For the given nexthop, returns the string diff --git a/staticd/static_routes.c b/staticd/static_routes.c index cba38183bbf0..cbe1c3c8c0be 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -33,10 +33,6 @@ void zebra_stable_node_cleanup(struct route_table *table, struct static_nexthop *nh; struct static_path *pn; struct static_route_info *si; - struct route_table *src_table; - struct route_node *src_node; - struct static_path *src_pn; - struct static_route_info *src_si; si = node->info; @@ -50,36 +46,6 @@ void zebra_stable_node_cleanup(struct route_table *table, static_path_list_del(&si->path_list, pn); XFREE(MTYPE_STATIC_PATH, pn); } - - /* clean up for dst table */ - src_table = srcdest_srcnode_table(node); - if (src_table) { - /* This means the route_node is part of the top - * hierarchy and refers to a destination prefix. - */ - for (src_node = route_top(src_table); src_node; - src_node = route_next(src_node)) { - src_si = src_node->info; - - frr_each_safe(static_path_list, - &src_si->path_list, src_pn) { - frr_each_safe(static_nexthop_list, - &src_pn->nexthop_list, - nh) { - static_nexthop_list_del( - &src_pn->nexthop_list, - nh); - XFREE(MTYPE_STATIC_NEXTHOP, nh); - } - static_path_list_del(&src_si->path_list, - src_pn); - XFREE(MTYPE_STATIC_PATH, src_pn); - } - - XFREE(MTYPE_STATIC_ROUTE, src_node->info); - } - } - XFREE(MTYPE_STATIC_ROUTE, node->info); } } @@ -124,28 +90,10 @@ struct route_node *static_add_route(afi_t afi, safi_t safi, struct prefix *p, return rn; } -/* To delete the srcnodes */ -static void static_del_src_route(struct route_node *rn) -{ - struct static_path *pn; - struct static_route_info *si; - - si = rn->info; - - frr_each_safe(static_path_list, &si->path_list, pn) { - static_del_path(pn); - } - - XFREE(MTYPE_STATIC_ROUTE, rn->info); - route_unlock_node(rn); -} - void static_del_route(struct route_node *rn) { struct static_path *pn; struct static_route_info *si; - struct route_table *src_table; - struct route_node *src_node; si = rn->info; @@ -153,17 +101,6 @@ void static_del_route(struct route_node *rn) static_del_path(pn); } - /* clean up for dst table */ - src_table = srcdest_srcnode_table(rn); - if (src_table) { - /* This means the route_node is part of the top hierarchy - * and refers to a destination prefix. - */ - for (src_node = route_top(src_table); src_node; - src_node = route_next(src_node)) { - static_del_src_route(src_node); - } - } XFREE(MTYPE_STATIC_ROUTE, rn->info); route_unlock_node(rn); } @@ -477,7 +414,7 @@ static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable, struct static_path *pn; struct static_route_info *si; - for (rn = route_top(stable); rn; rn = route_next(rn)) { + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { si = static_route_info_from_rnode(rn); if (!si) continue; @@ -517,7 +454,7 @@ static void static_enable_vrf(struct route_table *stable, afi_t afi, safi_t safi struct static_path *pn; struct static_route_info *si; - for (rn = route_top(stable); rn; rn = route_next(rn)) { + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { si = static_route_info_from_rnode(rn); if (!si) continue; @@ -575,7 +512,7 @@ static void static_cleanup_vrf(struct vrf *vrf, struct route_table *stable, struct static_path *pn; struct static_route_info *si; - for (rn = route_top(stable); rn; rn = route_next(rn)) { + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { si = static_route_info_from_rnode(rn); if (!si) continue; @@ -608,7 +545,7 @@ static void static_disable_vrf(struct route_table *stable, struct static_path *pn; struct static_route_info *si; - for (rn = route_top(stable); rn; rn = route_next(rn)) { + for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { si = static_route_info_from_rnode(rn); if (!si) continue; diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c index 710827a9ff49..78bc30500b94 100644 --- a/staticd/static_vrf.c +++ b/staticd/static_vrf.c @@ -51,10 +51,8 @@ struct static_vrf *static_vrf_alloc(const char *name) for (afi = AFI_IP; afi <= AFI_IP6; afi++) { for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { - if (afi == AFI_IP6) - table = srcdest_table_init(); - else - table = route_table_init(); + table = srcdest_table_init(); + table->cleanup = zebra_stable_node_cleanup; info = XCALLOC(MTYPE_STATIC_RTABLE_INFO, sizeof(struct stable_info)); @@ -63,7 +61,6 @@ struct static_vrf *static_vrf_alloc(const char *name) info->safi = safi; route_table_set_info(table, info); - table->cleanup = zebra_stable_node_cleanup; svrf->stable[afi][safi] = table; } } diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 2fadc1f0d463..ed2805d3eab9 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -79,7 +79,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) char xpath_seg[XPATH_MAXLEN]; char ab_xpath[XPATH_MAXLEN]; char buf_prefix[PREFIX_STRLEN]; - char buf_src_prefix[PREFIX_STRLEN] = {}; + char buf_src_prefix[PREFIX_STRLEN] = "::/0"; char buf_nh_type[PREFIX_STRLEN] = {}; char buf_tag[PREFIX_STRLEN]; uint8_t label_stack_id = 0; @@ -116,6 +116,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) } assert(!!str2prefix(args->prefix, &p)); + src = (struct prefix){ .family = p.family, .prefixlen = 0 }; switch (args->afi) { case AFI_IP: @@ -146,7 +147,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) return CMD_WARNING_CONFIG_FAILED; } - if (args->source) + if (src.prefixlen) prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix)); if (args->gateway) buf_gate_str = args->gateway; @@ -183,25 +184,10 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) static_get_nh_type(type, buf_nh_type, sizeof(buf_nh_type)); if (!args->delete) { - if (args->source) - snprintf(ab_xpath, sizeof(ab_xpath), - FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH, - "frr-staticd:staticd", "staticd", args->vrf, - buf_prefix, - yang_afi_safi_value2identity(args->afi, - args->safi), - buf_src_prefix, table_id, buf_nh_type, - args->nexthop_vrf, buf_gate_str, - args->interface_name); - else - snprintf(ab_xpath, sizeof(ab_xpath), - FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, - "frr-staticd:staticd", "staticd", args->vrf, - buf_prefix, - yang_afi_safi_value2identity(args->afi, - args->safi), - table_id, buf_nh_type, args->nexthop_vrf, - buf_gate_str, args->interface_name); + snprintf(ab_xpath, sizeof(ab_xpath), FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, + "frr-staticd:staticd", "staticd", args->vrf, buf_prefix, buf_src_prefix, + yang_afi_safi_value2identity(args->afi, args->safi), table_id, buf_nh_type, + args->nexthop_vrf, buf_gate_str, args->interface_name); /* * If there's already the same nexthop but with a different @@ -218,22 +204,9 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) } /* route + path procesing */ - if (args->source) - snprintf(xpath_prefix, sizeof(xpath_prefix), - FRR_S_ROUTE_SRC_INFO_KEY_XPATH, - "frr-staticd:staticd", "staticd", args->vrf, - buf_prefix, - yang_afi_safi_value2identity(args->afi, - args->safi), - buf_src_prefix, table_id, distance); - else - snprintf(xpath_prefix, sizeof(xpath_prefix), - FRR_STATIC_ROUTE_INFO_KEY_XPATH, - "frr-staticd:staticd", "staticd", args->vrf, - buf_prefix, - yang_afi_safi_value2identity(args->afi, - args->safi), - table_id, distance); + snprintf(xpath_prefix, sizeof(xpath_prefix), FRR_STATIC_ROUTE_INFO_KEY_XPATH, + "frr-staticd:staticd", "staticd", args->vrf, buf_prefix, buf_src_prefix, + yang_afi_safi_value2identity(args->afi, args->safi), table_id, distance); nb_cli_enqueue_change(vty, xpath_prefix, NB_OP_CREATE, NULL); @@ -412,51 +385,18 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) if (orig_seg) XFREE(MTYPE_TMP, orig_seg); } else { - if (args->source) { - if (args->distance) - snprintf(ab_xpath, sizeof(ab_xpath), - FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH, - "frr-staticd:staticd", "staticd", - args->vrf, buf_prefix, - yang_afi_safi_value2identity( - args->afi, args->safi), - buf_src_prefix, table_id, distance, - buf_nh_type, args->nexthop_vrf, - buf_gate_str, args->interface_name); - else - snprintf( - ab_xpath, sizeof(ab_xpath), - FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH, - "frr-staticd:staticd", "staticd", - args->vrf, buf_prefix, - yang_afi_safi_value2identity( - args->afi, args->safi), - buf_src_prefix, table_id, buf_nh_type, - args->nexthop_vrf, buf_gate_str, - args->interface_name); - } else { - if (args->distance) - snprintf(ab_xpath, sizeof(ab_xpath), - FRR_DEL_S_ROUTE_NH_KEY_XPATH, - "frr-staticd:staticd", "staticd", - args->vrf, buf_prefix, - yang_afi_safi_value2identity( - args->afi, args->safi), - table_id, distance, buf_nh_type, - args->nexthop_vrf, buf_gate_str, - args->interface_name); - else - snprintf( - ab_xpath, sizeof(ab_xpath), - FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, - "frr-staticd:staticd", "staticd", - args->vrf, buf_prefix, - yang_afi_safi_value2identity( - args->afi, args->safi), - table_id, buf_nh_type, - args->nexthop_vrf, buf_gate_str, - args->interface_name); - } + if (args->distance) + snprintf(ab_xpath, sizeof(ab_xpath), FRR_DEL_S_ROUTE_NH_KEY_XPATH, + "frr-staticd:staticd", "staticd", args->vrf, buf_prefix, + buf_src_prefix, yang_afi_safi_value2identity(args->afi, args->safi), + table_id, distance, buf_nh_type, args->nexthop_vrf, buf_gate_str, + args->interface_name); + else + snprintf(ab_xpath, sizeof(ab_xpath), + FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, "frr-staticd:staticd", + "staticd", args->vrf, buf_prefix, buf_src_prefix, + yang_afi_safi_value2identity(args->afi, args->safi), table_id, + buf_nh_type, args->nexthop_vrf, buf_gate_str, args->interface_name); dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath); if (!dnode) { @@ -1439,9 +1379,8 @@ static int srv6_seg_iter_cb(const struct lyd_node *dnode, void *arg) } static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, - const struct lyd_node *src, - const struct lyd_node *path, - const struct lyd_node *nexthop, bool show_defaults) + const struct lyd_node *path, const struct lyd_node *nexthop, + bool show_defaults) { const char *vrf; const char *afi_safi; @@ -1455,6 +1394,7 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, struct srv6_seg_iter seg_iter; const char *nexthop_vrf; uint32_t table_id; + struct prefix src_prefix; bool onlink; vrf = yang_dnode_get_string(route, "../../vrf"); @@ -1476,9 +1416,9 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, vty_out(vty, " %s", yang_dnode_get_string(route, "prefix")); - if (src) - vty_out(vty, " from %s", - yang_dnode_get_string(src, "src-prefix")); + yang_dnode_get_prefix(&src_prefix, route, "src-prefix"); + if (src_prefix.prefixlen) + vty_out(vty, " from %pFX", &src_prefix); nh_type = yang_dnode_get_enum(nexthop, "nh-type"); switch (nh_type) { @@ -1582,18 +1522,7 @@ static void static_nexthop_cli_show(struct vty *vty, const struct lyd_node *route = yang_dnode_get_parent(path, "route-list"); - nexthop_cli_show(vty, route, NULL, path, dnode, show_defaults); -} - -static void static_src_nexthop_cli_show(struct vty *vty, - const struct lyd_node *dnode, - bool show_defaults) -{ - const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list"); - const struct lyd_node *src = yang_dnode_get_parent(path, "src-list"); - const struct lyd_node *route = yang_dnode_get_parent(src, "route-list"); - - nexthop_cli_show(vty, route, src, path, dnode, show_defaults); + nexthop_cli_show(vty, route, path, dnode, show_defaults); } static int static_nexthop_cli_cmp(const struct lyd_node *dnode1, @@ -1658,6 +1587,8 @@ static int static_route_list_cli_cmp(const struct lyd_node *dnode1, afi_t afi1, afi2; safi_t safi1, safi2; struct prefix prefix1, prefix2; + struct prefix src_prefix1, src_prefix2; + int rv; afi_safi1 = yang_dnode_get_string(dnode1, "afi-safi"); yang_afi_safi_identity2value(afi_safi1, &afi1, &safi1); @@ -1673,19 +1604,13 @@ static int static_route_list_cli_cmp(const struct lyd_node *dnode1, yang_dnode_get_prefix(&prefix1, dnode1, "prefix"); yang_dnode_get_prefix(&prefix2, dnode2, "prefix"); + rv = prefix_cmp(&prefix1, &prefix2); + if (rv) + return rv; - return prefix_cmp(&prefix1, &prefix2); -} - -static int static_src_list_cli_cmp(const struct lyd_node *dnode1, - const struct lyd_node *dnode2) -{ - struct prefix prefix1, prefix2; - - yang_dnode_get_prefix(&prefix1, dnode1, "src-prefix"); - yang_dnode_get_prefix(&prefix2, dnode2, "src-prefix"); - - return prefix_cmp(&prefix1, &prefix2); + yang_dnode_get_prefix(&src_prefix1, dnode1, "src-prefix"); + yang_dnode_get_prefix(&src_prefix2, dnode2, "src-prefix"); + return prefix_cmp(&src_prefix1, &src_prefix2); } static int static_path_list_cli_cmp(const struct lyd_node *dnode1, @@ -1830,25 +1755,6 @@ const struct frr_yang_module_info frr_staticd_cli_info = { .cli_cmp = static_nexthop_cli_cmp, } }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list", - .cbs = { - .cli_cmp = static_src_list_cli_cmp, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list", - .cbs = { - .cli_cmp = static_path_list_cli_cmp, - } - }, - { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop", - .cbs = { - .cli_show = static_src_nexthop_cli_show, - .cli_cmp = static_nexthop_cli_cmp, - } - }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/segment-routing", .cbs = { diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index e87eaed00876..057193aa08b4 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -132,35 +132,37 @@ static int static_ifp_down(struct interface *ifp) static int route_notify_owner(ZAPI_CALLBACK_ARGS) { - struct prefix p; + struct prefix p, src_p, *src_pp; enum zapi_route_notify_owner note; uint32_t table_id; safi_t safi; - if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, ¬e, NULL, - &safi)) + if (!zapi_route_notify_decode_srcdest(zclient->ibuf, &p, &src_p, &table_id, ¬e, NULL, + &safi)) return -1; + src_pp = src_p.prefixlen ? &src_p : NULL; + switch (note) { case ZAPI_ROUTE_FAIL_INSTALL: - static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED); + static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_NOT_INSTALLED); zlog_warn("%s: Route %pFX failed to install for table: %u", __func__, &p, table_id); break; case ZAPI_ROUTE_BETTER_ADMIN_WON: - static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED); + static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_NOT_INSTALLED); zlog_warn( "%s: Route %pFX over-ridden by better route for table: %u", __func__, &p, table_id); break; case ZAPI_ROUTE_INSTALLED: - static_nht_mark_state(&p, safi, vrf_id, STATIC_INSTALLED); + static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_INSTALLED); break; case ZAPI_ROUTE_REMOVED: - static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED); + static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_NOT_INSTALLED); break; case ZAPI_ROUTE_REMOVE_FAIL: - static_nht_mark_state(&p, safi, vrf_id, STATIC_INSTALLED); + static_nht_mark_state(&p, src_pp, safi, vrf_id, STATIC_INSTALLED); zlog_warn("%s: Route %pFX failure to remove for table: %u", __func__, &p, table_id); break; @@ -226,8 +228,8 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched, nhtd->nh_num = nhr->nexthop_num; static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id); - static_nht_update(NULL, matched, nhr->nexthop_num, afi, - nhr->safi, nhtd->nh_vrf_id); + static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi, + nhtd->nh_vrf_id); } else zlog_err("No nhtd?"); } @@ -312,10 +314,13 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg) { struct static_path *pn = nh->pn; struct route_node *rn = pn->rn; + const struct prefix *p, *src_p; struct static_route_info *si = static_route_info_from_rnode(rn); struct static_nht_data *nhtd, lookup = {}; uint32_t cmd; + srcdest_rnode_prefixes(rn, &p, &src_p); + if (!static_zebra_nht_get_prefix(nh, &lookup.nh)) return; lookup.nh_vrf_id = nh->nh_vrf_id; @@ -351,8 +356,8 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg) if (nh->state == STATIC_NOT_INSTALLED || nh->state == STATIC_SENT_TO_ZEBRA) nh->state = STATIC_START; - static_nht_update(&rn->p, &nhtd->nh, nhtd->nh_num, afi, - si->safi, nh->nh_vrf_id); + static_nht_update(p, src_p, &nhtd->nh, nhtd->nh_num, afi, si->safi, + nh->nh_vrf_id); return; } diff --git a/tests/topotests/mgmt_tests/test_yang_mgmt.py b/tests/topotests/mgmt_tests/test_yang_mgmt.py index 52f6ba4db745..7b74eab6b7da 100644 --- a/tests/topotests/mgmt_tests/test_yang_mgmt.py +++ b/tests/topotests/mgmt_tests/test_yang_mgmt.py @@ -181,7 +181,7 @@ def test_mgmt_commit_check(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.2/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.2/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", "mgmt commit check", ] } @@ -194,7 +194,7 @@ def test_mgmt_commit_check(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.2/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.2/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", "mgmt commit check", ] } @@ -245,7 +245,7 @@ def test_mgmt_commit_apply(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.20/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.20/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", "mgmt commit apply", ] } @@ -258,7 +258,7 @@ def test_mgmt_commit_apply(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.20/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.20/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", "mgmt commit apply", ] } @@ -298,7 +298,7 @@ def test_mgmt_commit_abort(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.3/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.1.3/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", "mgmt commit abort", ] } @@ -350,7 +350,7 @@ def test_mgmt_delete_config(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.168.1.3/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.168.1.3/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/vrf default", "mgmt commit apply", ] } @@ -381,7 +381,7 @@ def test_mgmt_delete_config(request): raw_config = { "r1": { "raw_config": [ - "mgmt delete-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.168.1.3/32'][afi-safi='frr-routing:ipv4-unicast']", + "mgmt delete-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.168.1.3/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']", "mgmt commit apply", ] } @@ -657,7 +657,7 @@ def test_mgmt_chaos_stop_start_frr(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.11.200/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.11.200/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", "mgmt commit apply", ] } @@ -689,7 +689,7 @@ def test_mgmt_chaos_stop_start_frr(request): raw_config = { "r1": { "raw_config": [ - "mgmt delete-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.11.200/32'][afi-safi='frr-routing:ipv4-unicast']", + "mgmt delete-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.11.200/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']", "mgmt commit apply", ] } @@ -733,7 +733,7 @@ def test_mgmt_chaos_kill_daemon(request): raw_config = { "r1": { "raw_config": [ - "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.11.200/32'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", + "mgmt set-config /frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/route-list[prefix='192.1.11.200/32'][src-prefix='::/0'][afi-safi='frr-routing:ipv4-unicast']/path-list[table-id='0'][distance='1']/frr-nexthops/nexthop[nh-type='blackhole'][vrf='default'][gateway=''][interface='(null)']/bh-type unspec", "mgmt commit apply", ] } diff --git a/tests/topotests/static_simple/test_static_simple.py b/tests/topotests/static_simple/test_static_simple.py index bb3580a1d8b2..afde58fbf71e 100644 --- a/tests/topotests/static_simple/test_static_simple.py +++ b/tests/topotests/static_simple/test_static_simple.py @@ -61,6 +61,15 @@ def get_ip_networks(super_prefix, count): return tuple(network.subnets(count_log2))[0:count] +def get_src_networks(src_prefix, count, default=""): + if src_prefix is not None: + for net in get_ip_networks(src_prefix, count): + yield " from {}".format(net) + else: + for i in range(0, count): + yield default + + def enable_debug(router): router.vtysh_cmd("debug northbound callbacks configuration") @@ -70,7 +79,7 @@ def disable_debug(router): @retry(retry_timeout=30, initial_wait=0.1) -def check_kernel(r1, super_prefix, count, add, is_blackhole, vrf, matchvia): +def check_kernel(r1, super_prefix, src_prefix, count, add, is_blackhole, vrf, matchvia): network = ipaddress.ip_network(super_prefix) vrfstr = f" vrf {vrf}" if vrf else "" if network.version == 6: @@ -79,26 +88,30 @@ def check_kernel(r1, super_prefix, count, add, is_blackhole, vrf, matchvia): kernel = r1.run(f"ip -4 route show{vrfstr}") logger.debug("checking kernel routing table%s:\n%s", vrfstr, kernel) - for _, net in enumerate(get_ip_networks(super_prefix, count)): + for net, srcnet in zip( + get_ip_networks(super_prefix, count), get_src_networks(src_prefix, count) + ): + netfull = str(net) + srcnet if not add: - assert str(net) not in kernel + assert netfull + " nhid" not in kernel + assert netfull + " via" not in kernel continue if is_blackhole: - route = f"blackhole {str(net)} proto (static|196) metric 20" + route = f"blackhole {netfull}(?: dev lo)? proto (static|196) metric 20" else: route = ( - f"{str(net)}(?: nhid [0-9]+)? {matchvia} " - "proto (static|196) metric 20" + f"{netfull}(?: nhid [0-9]+)? {matchvia} proto (static|196) metric 20" ) assert re.search(route, kernel), f"Failed to find \n'{route}'\n in \n'{kernel}'" -def do_config( +def do_config_inner( r1, count, add=True, do_ipv6=False, + do_sadr=False, via=None, vrf=None, use_cli=False, @@ -109,11 +122,18 @@ def do_config( # # Set the route details # - - if vrf: - super_prefix = "2002::/48" if do_ipv6 else "20.0.0.0/8" + src_prefs = [None, None] + if do_ipv6 and do_sadr: + # intentionally using overlapping prefix + super_prefs = ["2001::/48", "2002::/48"] + src_prefs = ["2001:db8:1111::/48", "2001:db8:2222::/48"] + elif do_ipv6: + super_prefs = ["2001::/48", "2002::/48"] else: - super_prefix = "2001::/48" if do_ipv6 else "10.0.0.0/8" + super_prefs = ["10.0.0.0/8", "20.0.0.0/8"] + + super_prefix = super_prefs[1 if vrf else 0] + src_prefix = src_prefs[1 if vrf else 0] matchvia = "" if via == "blackhole": @@ -144,11 +164,13 @@ def do_config( if vrf: f.write("vrf {}\n".format(vrf)) - for _, net in enumerate(get_ip_networks(super_prefix, count)): + for net, srcnet in zip( + get_ip_networks(super_prefix, count), get_src_networks(src_prefix, count) + ): if add: - f.write("ip route {} {}\n".format(net, via)) + f.write("ip route {}{} {}\n".format(net, srcnet, via)) else: - f.write("no ip route {} {}\n".format(net, via)) + f.write("no ip route {}{} {}\n".format(net, srcnet, via)) # # Load config file. @@ -165,7 +187,9 @@ def do_config( # # Verify the results are in the kernel # - check_kernel(r1, super_prefix, count, add, via == "blackhole", vrf, matchvia) + check_kernel( + r1, super_prefix, src_prefix, count, add, via == "blackhole", vrf, matchvia + ) optyped = "added" if add else "removed" logger.debug( @@ -175,6 +199,12 @@ def do_config( ) +def do_config(*args, **kwargs): + do_config_inner(*args, do_ipv6=False, do_sadr=False, **kwargs) + do_config_inner(*args, do_ipv6=True, do_sadr=False, **kwargs) + do_config_inner(*args, do_ipv6=True, do_sadr=True, **kwargs) + + def guts(tgen, vrf, use_cli): if tgen.routers_have_failure(): pytest.skip(tgen.errors) @@ -183,20 +213,20 @@ def guts(tgen, vrf, use_cli): count = 10 step(f"add {count} via gateway", reset=True) - do_config(r1, count, True, False, vrf=vrf, use_cli=use_cli) + do_config(r1, count, True, vrf=vrf, use_cli=use_cli) step(f"remove {count} via gateway") - do_config(r1, count, False, False, vrf=vrf, use_cli=use_cli) + do_config(r1, count, False, vrf=vrf, use_cli=use_cli) via = f"lo-{vrf}" if vrf else "lo" step("add via loopback") - do_config(r1, 1, True, False, via=via, vrf=vrf, use_cli=use_cli) + do_config(r1, 1, True, via=via, vrf=vrf, use_cli=use_cli) step("remove via loopback") - do_config(r1, 1, False, False, via=via, vrf=vrf, use_cli=use_cli) + do_config(r1, 1, False, via=via, vrf=vrf, use_cli=use_cli) step("add via blackhole") - do_config(r1, 1, True, False, via="blackhole", vrf=vrf, use_cli=use_cli) + do_config(r1, 1, True, via="blackhole", vrf=vrf, use_cli=use_cli) step("remove via blackhole") - do_config(r1, 1, False, False, via="blackhole", vrf=vrf, use_cli=use_cli) + do_config(r1, 1, False, via="blackhole", vrf=vrf, use_cli=use_cli) def test_static_cli(tgen): diff --git a/yang/frr-staticd.yang b/yang/frr-staticd.yang index 904e2058e9c2..8d0e58c0a5c3 100644 --- a/yang/frr-staticd.yang +++ b/yang/frr-staticd.yang @@ -165,7 +165,7 @@ module frr-staticd { "Support for a 'staticd' pseudo-protocol instance consists of a list of routes."; list route-list { - key "prefix afi-safi"; + key "prefix src-prefix afi-safi"; description "List of staticd IP routes."; leaf prefix { @@ -173,6 +173,11 @@ module frr-staticd { description "IP prefix."; } + leaf src-prefix { + type inet:ipv6-prefix; + description + "IPv6 source prefix for dst-src routes"; + } leaf afi-safi { type identityref { base frr-rt:afi-safi-type; @@ -180,6 +185,12 @@ module frr-staticd { description "AFI-SAFI type."; } + /* note dst-src routes are semantically invalid in MRIB */ + must "afi-safi = 'frr-rt:ipv6-unicast' + or afi-safi = 'frr-rt:ipv6-labeled-unicast' + or afi-safi = 'frr-rt:l3vpn-ipv6-unicast' + or src-prefix = '::/0' + "; uses staticd-prefix-attributes { augment "path-list/frr-nexthops/nexthop" { @@ -194,17 +205,6 @@ module frr-staticd { } } } - - list src-list { - key "src-prefix"; - leaf src-prefix { - type inet:ipv6-prefix; - description - "IPv6 source prefix"; - } - - uses staticd-prefix-attributes; - } } container segment-routing { diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index b32882e85834..d696b198598b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2588,10 +2588,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx } } - if ((!fpm && kernel_nexthops_supported() - && (!proto_nexthops_only() - || is_proto_nhg(dplane_ctx_get_nhe_id(ctx), 0))) - || (fpm && force_nhg)) { + if ((!fpm && kernel_nexthops_supported() && + (!proto_nexthops_only() || is_proto_nhg(dplane_ctx_get_nhe_id(ctx), 0)) && + (!src_p || !src_p->prefixlen)) || + (fpm && force_nhg)) { /* Kernel supports nexthop objects */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("%s: %pFX nhg_id is %u", __func__, p, diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index f32d8ea6c65c..e9d554ba3d30 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -740,6 +740,10 @@ static int route_notify_internal(const struct route_node *rn, int type, struct zserv *client; struct stream *s; uint8_t blen; + const struct prefix *p, *src_p; + struct prefix src_dummy = {}; + + srcdest_rnode_prefixes(rn, &p, &src_p); client = zserv_find_client(type, instance); if (!client || !client->notify_owner) { @@ -771,9 +775,17 @@ static int route_notify_internal(const struct route_node *rn, int type, stream_putc(s, rn->p.family); - blen = prefix_blen(&rn->p); - stream_putc(s, rn->p.prefixlen); - stream_put(s, &rn->p.u.prefix, blen); + blen = prefix_blen(p); + stream_putc(s, p->prefixlen); + stream_put(s, &p->u.prefix, blen); + + if (!src_p) { + src_dummy.family = p->family; + src_p = &src_dummy; + } + blen = prefix_blen(src_p); + stream_putc(s, src_p->prefixlen); + stream_put(s, &src_p->u.prefix, blen); stream_putl(s, table_id);