diff options
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/connected.c | 21 | ||||
| -rw-r--r-- | zebra/main.c | 15 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 14 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 27 | ||||
| -rw-r--r-- | zebra/zapi_msg.h | 3 | ||||
| -rw-r--r-- | zebra/zebra_nb_config.c | 28 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 38 | ||||
| -rw-r--r-- | zebra/zebra_routemap.c | 283 | ||||
| -rw-r--r-- | zebra/zebra_router.c | 10 | ||||
| -rw-r--r-- | zebra/zebra_router.h | 5 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 47 |
11 files changed, 293 insertions, 198 deletions
diff --git a/zebra/connected.c b/zebra/connected.c index 6a1efc3e65..70ea2e3805 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -41,6 +41,7 @@ #include "zebra/zebra_mpls.h" #include "zebra/debug.h" #include "zebra/zebra_errors.h" +#include "zebra/zebra_router.h" /* communicate the withdrawal of a connected address */ static void connected_withdraw(struct connected *ifc) @@ -207,6 +208,7 @@ void connected_up(struct interface *ifp, struct connected *ifc) }; struct zebra_vrf *zvrf; uint32_t metric; + uint32_t flags = 0; zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id); if (!zvrf) { @@ -251,11 +253,22 @@ void connected_up(struct interface *ifp, struct connected *ifc) metric = (ifc->metric < (uint32_t)METRIC_MAX) ? ifc->metric : ifp->metric; - rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0); - rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, - 0, 0, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0); + /* + * Since we are hand creating the connected routes + * in our main routing table, *if* we are working + * in an offloaded environment then we need to + * pretend like the route is offloaded so everything + * else will work + */ + if (zrouter.asic_offloaded) + flags |= ZEBRA_FLAG_OFFLOADED; + + rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0, + flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0); + + rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0, + flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0); /* Schedule LSP forwarding entries for processing, if appropriate. */ if (zvrf->vrf->vrf_id == VRF_DEFAULT) { diff --git a/zebra/main.c b/zebra/main.c index ced29e1a25..55fd3244cb 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -83,6 +83,8 @@ uint32_t nl_rcvbufsize = 4194304; #endif /* HAVE_NETLINK */ #define OPTION_V6_RR_SEMANTICS 2000 +#define OPTION_ASIC_OFFLOAD 2001 + /* Command line options. */ const struct option longopts[] = { {"batch", no_argument, NULL, 'b'}, @@ -92,6 +94,7 @@ const struct option longopts[] = { {"retain", no_argument, NULL, 'r'}, {"vrfdefaultname", required_argument, NULL, 'o'}, {"graceful_restart", required_argument, NULL, 'K'}, + {"asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD}, #ifdef HAVE_NETLINK {"vrfwnetns", no_argument, NULL, 'n'}, {"nl-bufsize", required_argument, NULL, 's'}, @@ -281,6 +284,8 @@ int main(int argc, char **argv) char *vrf_default_name_configured = NULL; struct sockaddr_storage dummy; socklen_t dummylen; + bool asic_offload = false; + bool notify_on_ack = true; graceful_restart = 0; vrf_configure_backend(VRF_BACKEND_VRF_LITE); @@ -301,6 +306,7 @@ int main(int argc, char **argv) " -r, --retain When program terminates, retain added route by zebra.\n" " -o, --vrfdefaultname Set default VRF name.\n" " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" + " -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n" #ifdef HAVE_NETLINK " -n, --vrfwnetns Use NetNS as VRF backend\n" " -s, --nl-bufsize Set netlink receive buffer size\n" @@ -366,6 +372,13 @@ int main(int argc, char **argv) case OPTION_V6_RR_SEMANTICS: v6_rr_semantics = true; break; + case OPTION_ASIC_OFFLOAD: + if (!strcmp(optarg, "notify_on_offload")) + notify_on_ack = false; + if (!strcmp(optarg, "notify_on_ack")) + notify_on_ack = true; + asic_offload = true; + break; #endif /* HAVE_NETLINK */ default: frr_help_exit(1); @@ -376,7 +389,7 @@ int main(int argc, char **argv) zrouter.master = frr_init(); /* Zebra related initialize. */ - zebra_router_init(); + zebra_router_init(asic_offload, notify_on_ack); zserv_init(); rib_init(); zebra_if_init(); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ef51989a0c..3402edf467 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -642,7 +642,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, selfroute = is_selfroute(rtm->rtm_protocol); - if (!startup && selfroute && h->nlmsg_type == RTM_NEWROUTE) { + if (!startup && selfroute + && h->nlmsg_type == RTM_NEWROUTE + && !zrouter.asic_offloaded) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("Route type: %d Received that we think we have originated, ignoring", rtm->rtm_protocol); @@ -672,6 +674,8 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, flags |= ZEBRA_FLAG_TRAPPED; if (rtm->rtm_flags & RTM_F_OFFLOAD) flags |= ZEBRA_FLAG_OFFLOADED; + if (rtm->rtm_flags & RTM_F_OFFLOAD_FAILED) + flags |= ZEBRA_FLAG_OFFLOAD_FAILED; /* Route which inserted by Zebra. */ if (selfroute) { @@ -3179,10 +3183,14 @@ ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, void *data, update_flags = dplane_ctx_mac_get_update_flags(ctx); if (update_flags & DPLANE_MAC_REMOTE) { flags |= NTF_SELF; - if (dplane_ctx_mac_is_sticky(ctx)) + if (dplane_ctx_mac_is_sticky(ctx)) { + /* NUD_NOARP prevents the entry from expiring */ + state |= NUD_NOARP; + /* sticky the entry from moving */ flags |= NTF_STICKY; - else + } else { flags |= NTF_EXT_LEARNED; + } /* if it was static-local previously we need to clear the * notify flags on replace with remote */ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 18017c9700..1d68019909 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -742,7 +742,8 @@ static int nhg_notify(uint16_t type, uint16_t instance, uint32_t id, static int route_notify_internal(const struct prefix *p, int type, uint16_t instance, vrf_id_t vrf_id, uint32_t table_id, - enum zapi_route_notify_owner note) + enum zapi_route_notify_owner note, + afi_t afi, safi_t safi) { struct zserv *client; struct stream *s; @@ -778,16 +779,21 @@ static int route_notify_internal(const struct prefix *p, int type, stream_putl(s, table_id); + /* Encode AFI, SAFI in the message */ + stream_putc(s, afi); + stream_putc(s, safi); + stream_putw_at(s, 0, stream_get_endp(s)); return zserv_send_message(client, s); } int zsend_route_notify_owner(struct route_entry *re, const struct prefix *p, - enum zapi_route_notify_owner note) + enum zapi_route_notify_owner note, + afi_t afi, safi_t safi) { return (route_notify_internal(p, re->type, re->instance, re->vrf_id, - re->table, note)); + re->table, note, afi, safi)); } /* @@ -801,7 +807,19 @@ int zsend_route_notify_owner_ctx(const struct zebra_dplane_ctx *ctx, dplane_ctx_get_instance(ctx), dplane_ctx_get_vrf(ctx), dplane_ctx_get_table(ctx), - note)); + note, + dplane_ctx_get_afi(ctx), + dplane_ctx_get_safi(ctx))); +} + +static void zread_route_notify_request(ZAPI_HANDLER_ARGS) +{ + uint8_t notify; + + STREAM_GETC(msg, notify); + client->notify_owner = notify; +stream_failure: + return; } void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx, @@ -3275,6 +3293,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_NEIGH_DISCOVER] = zread_neigh_discover, [ZEBRA_NHG_ADD] = zread_nhg_add, [ZEBRA_NHG_DEL] = zread_nhg_del, + [ZEBRA_ROUTE_NOTIFY_REQUEST] = zread_route_notify_request, }; /* diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 9f23a313bf..efc52059b6 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -77,7 +77,8 @@ extern int zsend_interface_link_params(struct zserv *zclient, extern int zsend_pw_update(struct zserv *client, struct zebra_pw *pw); extern int zsend_route_notify_owner(struct route_entry *re, const struct prefix *p, - enum zapi_route_notify_owner note); + enum zapi_route_notify_owner note, + afi_t afi, safi_t safi); extern int zsend_route_notify_owner_ctx(const struct zebra_dplane_ctx *ctx, enum zapi_route_notify_owner note); diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index df95770307..ea2e20ed3b 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -1550,12 +1550,14 @@ int lib_route_map_entry_set_action_source_v4_modify( if (pif != NULL) break; } - if (pif == NULL) { - snprintf(args->errmsg, args->errmsg_len, - "is not a local address: %s", - yang_dnode_get_string(args->dnode, NULL)); - return NB_ERR_VALIDATION; - } + /* + * On startup the local address *may* not have come up + * yet. We need to allow startup configuration of + * set src or we are fudged. Log it for future fun + */ + if (pif == NULL) + zlog_warn("set src %pI4 is not a local address", + &p.u.prefix4); return NB_OK; case NB_EV_PREPARE: case NB_EV_ABORT: @@ -1618,12 +1620,14 @@ int lib_route_map_entry_set_action_source_v6_modify( if (pif != NULL) break; } - if (pif == NULL) { - snprintf(args->errmsg, args->errmsg_len, - "is not a local adddress: %s", - yang_dnode_get_string(args->dnode, NULL)); - return NB_ERR_VALIDATION; - } + /* + * On startup the local address *may* not have come up + * yet. We need to allow startup configuration of + * set src or we are fudged. Log it for future fun + */ + if (pif == NULL) + zlog_warn("set src %pI6 is not a local address", + &p.u.prefix6); return NB_OK; case NB_EV_PREPARE: case NB_EV_ABORT: diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index e76ecc85a6..569b23573c 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -481,7 +481,8 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, * know that they've lost */ if (old && (old != re) && (old->type != re->type)) - zsend_route_notify_owner(old, p, ZAPI_ROUTE_BETTER_ADMIN_WON); + zsend_route_notify_owner(old, p, ZAPI_ROUTE_BETTER_ADMIN_WON, + info->afi, info->safi); /* Update fib selection */ dest->selected_fib = re; @@ -1748,6 +1749,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) uint32_t seq; rib_dest_t *dest; bool fib_changed = false; + struct rib_table_info *info; zvrf = vrf_info_lookup(dplane_ctx_get_vrf(ctx)); vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); @@ -1767,6 +1769,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) dest = rib_dest_from_rnode(rn); srcdest_rnode_prefixes(rn, &dest_pfx, &src_pfx); + info = srcdest_rnode_table_info(rn); op = dplane_ctx_get_op(ctx); status = dplane_ctx_get_status(ctx); @@ -1818,8 +1821,12 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) "%s(%u):%pFX Stale dplane result for re %p", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dest_pfx, re); - } else - UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); + } else { + if (!zrouter.asic_offloaded || + (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED) || + CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))) + UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); + } } if (old_re) { @@ -1896,8 +1903,23 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) zvrf->installs++; /* Notify route owner */ - zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED); - + if (zebra_router_notify_on_ack()) + zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED); + else { + if (re) { + if (CHECK_FLAG(re->flags, + ZEBRA_FLAG_OFFLOADED)) + zsend_route_notify_owner_ctx( + ctx, + ZAPI_ROUTE_INSTALLED); + if (CHECK_FLAG( + re->flags, + ZEBRA_FLAG_OFFLOAD_FAILED)) + zsend_route_notify_owner_ctx( + ctx, + ZAPI_ROUTE_FAIL_INSTALL); + } + } } else { if (re) { SET_FLAG(re->status, ROUTE_ENTRY_FAILED); @@ -1906,7 +1928,8 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) SET_FLAG(old_re->status, ROUTE_ENTRY_FAILED); if (re) zsend_route_notify_owner(re, dest_pfx, - ZAPI_ROUTE_FAIL_INSTALL); + ZAPI_ROUTE_FAIL_INSTALL, + info->afi, info->safi); zlog_warn("%s(%u:%u):%pFX: Route install failed", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), @@ -2063,7 +2086,8 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) } /* Ensure we clear the QUEUED flag */ - UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); + if (!zrouter.asic_offloaded) + UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); /* Is this a notification that ... matters? We mostly care about * the route that is currently selected for installation; we may also diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 294f2c17ff..7b0a1e3d9c 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -64,19 +64,17 @@ static void zebra_route_map_set_delay_timer(uint32_t value); * Match function return 1 if match is success else return 0 */ static enum route_map_cmd_result_t -route_match_tag(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) +route_match_tag(void *rule, const struct prefix *prefix, void *object) { route_tag_t *tag; struct nh_rmap_obj *nh_data; - if (type == RMAP_ZEBRA) { - tag = rule; - nh_data = object; + tag = rule; + nh_data = object; + + if (nh_data->tag == *tag) + return RMAP_MATCH; - if (nh_data->tag == *tag) - return RMAP_MATCH; - } return RMAP_NOMATCH; } @@ -92,25 +90,23 @@ static const struct route_map_rule_cmd route_match_tag_cmd = { /* `match interface IFNAME' */ /* Match function return 1 if match is success else return zero. */ static enum route_map_cmd_result_t -route_match_interface(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) +route_match_interface(void *rule, const struct prefix *prefix, void *object) { struct nh_rmap_obj *nh_data; char *ifname = rule; ifindex_t ifindex; - if (type == RMAP_ZEBRA) { - if (strcasecmp(ifname, "any") == 0) - return RMAP_MATCH; - nh_data = object; - if (!nh_data || !nh_data->nexthop) - return RMAP_NOMATCH; - ifindex = ifname2ifindex(ifname, nh_data->vrf_id); - if (ifindex == 0) - return RMAP_NOMATCH; - if (nh_data->nexthop->ifindex == ifindex) - return RMAP_MATCH; - } + if (strcasecmp(ifname, "any") == 0) + return RMAP_MATCH; + nh_data = object; + if (!nh_data || !nh_data->nexthop) + return RMAP_NOMATCH; + ifindex = ifname2ifindex(ifname, nh_data->vrf_id); + if (ifindex == 0) + return RMAP_NOMATCH; + if (nh_data->nexthop->ifindex == ifindex) + return RMAP_MATCH; + return RMAP_NOMATCH; } @@ -938,40 +934,35 @@ DEFPY_YANG (show_ipv6_protocol_nht, /* Match function return 1 if match is success else return zero. */ static enum route_map_cmd_result_t -route_match_ip_next_hop(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) +route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object) { struct access_list *alist; struct nh_rmap_obj *nh_data; struct prefix_ipv4 p; - if (type == RMAP_ZEBRA) { - nh_data = object; - if (!nh_data) - return RMAP_NOMATCH; - - switch (nh_data->nexthop->type) { - case NEXTHOP_TYPE_IFINDEX: - /* Interface routes can't match ip next-hop */ - return RMAP_NOMATCH; - case NEXTHOP_TYPE_IPV4_IFINDEX: - case NEXTHOP_TYPE_IPV4: - p.family = AF_INET; - p.prefix = nh_data->nexthop->gate.ipv4; - p.prefixlen = IPV4_MAX_BITLEN; - break; - default: - return RMAP_NOMATCH; - } - alist = access_list_lookup(AFI_IP, (char *)rule); - if (alist == NULL) - return RMAP_NOMATCH; + nh_data = object; + if (!nh_data) + return RMAP_NOMATCH; - return (access_list_apply(alist, &p) == FILTER_DENY - ? RMAP_NOMATCH - : RMAP_MATCH); + switch (nh_data->nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + /* Interface routes can't match ip next-hop */ + return RMAP_NOMATCH; + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV4: + p.family = AF_INET; + p.prefix = nh_data->nexthop->gate.ipv4; + p.prefixlen = IPV4_MAX_BITLEN; + break; + default: + return RMAP_NOMATCH; } - return RMAP_NOMATCH; + alist = access_list_lookup(AFI_IP, (char *)rule); + if (alist == NULL) + return RMAP_NOMATCH; + + return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH + : RMAP_MATCH); } /* Route map `ip next-hop' match statement. `arg' should be @@ -999,39 +990,35 @@ static const struct route_map_rule_cmd route_match_ip_next_hop_cmd = { static enum route_map_cmd_result_t route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { struct prefix_list *plist; struct nh_rmap_obj *nh_data; struct prefix_ipv4 p; - if (type == RMAP_ZEBRA) { - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) - return RMAP_NOMATCH; - - switch (nh_data->nexthop->type) { - case NEXTHOP_TYPE_IFINDEX: - /* Interface routes can't match ip next-hop */ - return RMAP_NOMATCH; - case NEXTHOP_TYPE_IPV4_IFINDEX: - case NEXTHOP_TYPE_IPV4: - p.family = AF_INET; - p.prefix = nh_data->nexthop->gate.ipv4; - p.prefixlen = IPV4_MAX_BITLEN; - break; - default: - return RMAP_NOMATCH; - } - plist = prefix_list_lookup(AFI_IP, (char *)rule); - if (plist == NULL) - return RMAP_NOMATCH; + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data) + return RMAP_NOMATCH; - return (prefix_list_apply(plist, &p) == PREFIX_DENY - ? RMAP_NOMATCH - : RMAP_MATCH); + switch (nh_data->nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + /* Interface routes can't match ip next-hop */ + return RMAP_NOMATCH; + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV4: + p.family = AF_INET; + p.prefix = nh_data->nexthop->gate.ipv4; + p.prefixlen = IPV4_MAX_BITLEN; + break; + default: + return RMAP_NOMATCH; } - return RMAP_NOMATCH; + plist = prefix_list_lookup(AFI_IP, (char *)rule); + if (plist == NULL) + return RMAP_NOMATCH; + + return (prefix_list_apply(plist, &p) == PREFIX_DENY ? RMAP_NOMATCH + : RMAP_MATCH); } static void *route_match_ip_next_hop_prefix_list_compile(const char *arg) @@ -1058,34 +1045,28 @@ static const struct route_map_rule_cmd zero. */ static enum route_map_cmd_result_t route_match_address(afi_t afi, void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { struct access_list *alist; - if (type == RMAP_ZEBRA) { - alist = access_list_lookup(afi, (char *)rule); - if (alist == NULL) - return RMAP_NOMATCH; + alist = access_list_lookup(afi, (char *)rule); + if (alist == NULL) + return RMAP_NOMATCH; - return (access_list_apply(alist, prefix) == FILTER_DENY - ? RMAP_NOMATCH - : RMAP_MATCH); - } - return RMAP_NOMATCH; + return (access_list_apply(alist, prefix) == FILTER_DENY ? RMAP_NOMATCH + : RMAP_MATCH); } static enum route_map_cmd_result_t -route_match_ip_address(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) +route_match_ip_address(void *rule, const struct prefix *prefix, void *object) { - return route_match_address(AFI_IP, rule, prefix, type, object); + return route_match_address(AFI_IP, rule, prefix, object); } static enum route_map_cmd_result_t -route_match_ipv6_address(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) +route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object) { - return route_match_address(AFI_IP6, rule, prefix, type, object); + return route_match_address(AFI_IP6, rule, prefix, object); } /* Route map `ip address' match statement. `arg' should be @@ -1121,28 +1102,23 @@ static const struct route_map_rule_cmd route_match_ipv6_address_cmd = { static enum route_map_cmd_result_t route_match_address_prefix_list(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object, afi_t afi) + void *object, afi_t afi) { struct prefix_list *plist; - if (type == RMAP_ZEBRA) { - plist = prefix_list_lookup(afi, (char *)rule); - if (plist == NULL) - return RMAP_NOMATCH; + plist = prefix_list_lookup(afi, (char *)rule); + if (plist == NULL) + return RMAP_NOMATCH; - return (prefix_list_apply(plist, prefix) == PREFIX_DENY - ? RMAP_NOMATCH - : RMAP_MATCH); - } - return RMAP_NOMATCH; + return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH + : RMAP_MATCH); } static enum route_map_cmd_result_t route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { - return (route_match_address_prefix_list(rule, prefix, type, object, - AFI_IP)); + return (route_match_address_prefix_list(rule, prefix, object, AFI_IP)); } static void *route_match_address_prefix_list_compile(const char *arg) @@ -1165,10 +1141,9 @@ static const struct route_map_rule_cmd static enum route_map_cmd_result_t route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { - return (route_match_address_prefix_list(rule, prefix, type, object, - AFI_IP6)); + return (route_match_address_prefix_list(rule, prefix, object, AFI_IP6)); } static const struct route_map_rule_cmd @@ -1183,11 +1158,11 @@ static const struct route_map_rule_cmd static enum route_map_cmd_result_t route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { struct nh_rmap_obj *nh_data; - if (type == RMAP_ZEBRA && prefix->family == AF_INET6) { + if (prefix->family == AF_INET6) { nh_data = (struct nh_rmap_obj *)object; if (!nh_data) return RMAP_NOMATCH; @@ -1195,6 +1170,7 @@ route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix, if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) return RMAP_MATCH; } + return RMAP_NOMATCH; } @@ -1220,15 +1196,11 @@ static const struct route_map_rule_cmd static enum route_map_cmd_result_t route_match_address_prefix_len(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { uint32_t *prefixlen = (uint32_t *)rule; - if (type == RMAP_ZEBRA) { - return ((prefix->prefixlen == *prefixlen) ? RMAP_MATCH - : RMAP_NOMATCH); - } - return RMAP_NOMATCH; + return ((prefix->prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH); } static void *route_match_address_prefix_len_compile(const char *arg) @@ -1277,34 +1249,30 @@ static const struct route_map_rule_cmd static enum route_map_cmd_result_t route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { uint32_t *prefixlen = (uint32_t *)rule; struct nh_rmap_obj *nh_data; struct prefix_ipv4 p; - if (type == RMAP_ZEBRA) { - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data || !nh_data->nexthop) - return RMAP_NOMATCH; + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data || !nh_data->nexthop) + return RMAP_NOMATCH; - switch (nh_data->nexthop->type) { - case NEXTHOP_TYPE_IFINDEX: - /* Interface routes can't match ip next-hop */ - return RMAP_NOMATCH; - case NEXTHOP_TYPE_IPV4_IFINDEX: - case NEXTHOP_TYPE_IPV4: - p.family = AF_INET; - p.prefix = nh_data->nexthop->gate.ipv4; - p.prefixlen = IPV4_MAX_BITLEN; - break; - default: - return RMAP_NOMATCH; - } - return ((p.prefixlen == *prefixlen) ? RMAP_MATCH - : RMAP_NOMATCH); + switch (nh_data->nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + /* Interface routes can't match ip next-hop */ + return RMAP_NOMATCH; + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV4: + p.family = AF_INET; + p.prefix = nh_data->nexthop->gate.ipv4; + p.prefixlen = IPV4_MAX_BITLEN; + break; + default: + return RMAP_NOMATCH; } - return RMAP_NOMATCH; + return ((p.prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH); } static const struct route_map_rule_cmd @@ -1319,11 +1287,11 @@ static const struct route_map_rule_cmd static enum route_map_cmd_result_t route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) + void *object) { struct nh_rmap_obj *nh_data; - if (type == RMAP_ZEBRA && prefix->family == AF_INET) { + if (prefix->family == AF_INET) { nh_data = (struct nh_rmap_obj *)object; if (!nh_data) return RMAP_NOMATCH; @@ -1331,6 +1299,7 @@ route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) return RMAP_MATCH; } + return RMAP_NOMATCH; } @@ -1355,21 +1324,17 @@ static const struct route_map_rule_cmd /* `match source-protocol PROTOCOL' */ static enum route_map_cmd_result_t -route_match_source_protocol(void *rule, const struct prefix *p, - route_map_object_t type, void *object) +route_match_source_protocol(void *rule, const struct prefix *p, void *object) { uint32_t *rib_type = (uint32_t *)rule; struct nh_rmap_obj *nh_data; - if (type == RMAP_ZEBRA) { - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) - return RMAP_NOMATCH; + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data) + return RMAP_NOMATCH; - return ((nh_data->source_protocol == *rib_type) ? RMAP_MATCH - : RMAP_NOMATCH); - } - return RMAP_NOMATCH; + return ((nh_data->source_protocol == *rib_type) ? RMAP_MATCH + : RMAP_NOMATCH); } static void *route_match_source_protocol_compile(const char *arg) @@ -1399,15 +1364,11 @@ static const struct route_map_rule_cmd route_match_source_protocol_cmd = { /* `source-instance` */ static enum route_map_cmd_result_t -route_match_source_instance(void *rule, const struct prefix *p, - route_map_object_t type, void *object) +route_match_source_instance(void *rule, const struct prefix *p, void *object) { uint8_t *instance = (uint8_t *)rule; struct nh_rmap_obj *nh_data; - if (type != RMAP_ZEBRA) - return RMAP_NOMATCH; - nh_data = (struct nh_rmap_obj *)object; if (!nh_data) return RMAP_NOMATCH; @@ -1444,15 +1405,13 @@ static const struct route_map_rule_cmd route_match_source_instance_cmd = { /* Set src. */ static enum route_map_cmd_result_t -route_set_src(void *rule, const struct prefix *prefix, route_map_object_t type, - void *object) +route_set_src(void *rule, const struct prefix *prefix, void *object) { struct nh_rmap_obj *nh_data; - if (type == RMAP_ZEBRA) { - nh_data = (struct nh_rmap_obj *)object; - nh_data->nexthop->rmap_src = *(union g_addr *)rule; - } + nh_data = (struct nh_rmap_obj *)object; + nh_data->nexthop->rmap_src = *(union g_addr *)rule; + return RMAP_OKAY; } @@ -1738,7 +1697,7 @@ zebra_route_map_check(int family, int rib_type, uint8_t instance, if (!rmap && PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_MAX)) rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX); if (rmap) { - ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); + ret = route_map_apply(rmap, p, &nh_obj); } return (ret); @@ -1782,7 +1741,7 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance, if (re_type >= 0 && re_type < ZEBRA_ROUTE_MAX) rmap = route_map_lookup_by_name(rmap_name); if (rmap) { - ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); + ret = route_map_apply(rmap, p, &nh_obj); } return (ret); @@ -1810,7 +1769,7 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, if (!rmap && NHT_RM_MAP(zvrf, afi, ZEBRA_ROUTE_MAX)) rmap = NHT_RM_MAP(zvrf, afi, ZEBRA_ROUTE_MAX); if (rmap) - ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); + ret = route_map_apply(rmap, p, &nh_obj); return ret; } diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index fc4390f7f8..249ec38a69 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -257,7 +257,12 @@ void zebra_router_terminate(void) hash_free(zrouter.iptable_hash); } -void zebra_router_init(void) +bool zebra_router_notify_on_ack(void) +{ + return !zrouter.asic_offloaded || zrouter.notify_on_ack; +} + +void zebra_router_init(bool asic_offload, bool notify_on_ack) { zrouter.sequence_num = 0; @@ -291,5 +296,6 @@ void zebra_router_init(void) hash_create_size(8, zebra_nhg_id_key, zebra_nhg_hash_id_equal, "Zebra Router Nexthop Groups ID index"); - zrouter.asic_offloaded = false; + zrouter.asic_offloaded = asic_offload; + zrouter.notify_on_ack = notify_on_ack; } diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 8651a01e9f..08c5fcaf8d 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -210,13 +210,14 @@ struct zebra_router { * Does the underlying system provide an asic offload */ bool asic_offloaded; + bool notify_on_ack; }; #define GRACEFUL_RESTART_TIME 60 extern struct zebra_router zrouter; -extern void zebra_router_init(void); +extern void zebra_router_init(bool asic_offload, bool notify_on_ack); extern void zebra_router_cleanup(void); extern void zebra_router_terminate(void); @@ -255,6 +256,8 @@ extern void multicast_mode_ipv4_set(enum multicast_mode mode); extern enum multicast_mode multicast_mode_ipv4_get(void); +extern bool zebra_router_notify_on_ack(void); + /* zebra_northbound.c */ extern const struct frr_yang_module_info frr_zebra_info; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index ab7d2845e7..ea7baa2565 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -204,12 +204,16 @@ static char re_status_output_char(const struct route_entry *re, star_p = true; } + if (zrouter.asic_offloaded && + CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED)) + return 'q'; + if (zrouter.asic_offloaded && CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED)) return 't'; if (zrouter.asic_offloaded - && !CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) + && CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED)) return 'o'; if (star_p) @@ -870,6 +874,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) json_object_boolean_true_add(json_route, "offloaded"); + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED)) + json_object_boolean_false_add(json_route, "offloaded"); + if (re->tag) json_object_int_add(json_route, "tag", re->tag); @@ -2005,6 +2012,8 @@ static void vty_show_ip_route_summary(struct vty *vty, #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; + uint32_t offload_cnt[ZEBRA_ROUTE_TOTAL + 1]; + uint32_t trap_cnt[ZEBRA_ROUTE_TOTAL + 1]; uint32_t i; uint32_t is_ibgp; json_object *json_route_summary = NULL; @@ -2012,6 +2021,8 @@ static void vty_show_ip_route_summary(struct vty *vty, memset(&rib_cnt, 0, sizeof(rib_cnt)); memset(&fib_cnt, 0, sizeof(fib_cnt)); + memset(&offload_cnt, 0, sizeof(offload_cnt)); + memset(&trap_cnt, 0, sizeof(trap_cnt)); if (use_json) { json_route_summary = json_object_new_object(); @@ -2039,6 +2050,20 @@ static void vty_show_ip_route_summary(struct vty *vty, else fib_cnt[re->type]++; } + + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED)) { + if (is_ibgp) + trap_cnt[ZEBRA_ROUTE_IBGP]++; + else + trap_cnt[re->type]++; + } + + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) { + if (is_ibgp) + offload_cnt[ZEBRA_ROUTE_IBGP]++; + else + offload_cnt[re->type]++; + } } if (!use_json) @@ -2062,6 +2087,13 @@ static void vty_show_ip_route_summary(struct vty *vty, json_object_int_add( json_route_ebgp, "rib", rib_cnt[ZEBRA_ROUTE_BGP]); + json_object_int_add( + json_route_ebgp, "fibOffLoaded", + offload_cnt[ZEBRA_ROUTE_BGP]); + json_object_int_add( + json_route_ebgp, "fibTrapped", + trap_cnt[ZEBRA_ROUTE_BGP]); + json_object_string_add(json_route_ebgp, "type", "ebgp"); json_object_array_add(json_route_routes, @@ -2076,6 +2108,12 @@ static void vty_show_ip_route_summary(struct vty *vty, json_object_int_add( json_route_ibgp, "rib", rib_cnt[ZEBRA_ROUTE_IBGP]); + json_object_int_add( + json_route_ibgp, "fibOffLoaded", + offload_cnt[ZEBRA_ROUTE_IBGP]); + json_object_int_add( + json_route_ibgp, "fibTrapped", + trap_cnt[ZEBRA_ROUTE_IBGP]); json_object_string_add(json_route_ibgp, "type", "ibgp"); json_object_array_add(json_route_routes, @@ -2099,6 +2137,13 @@ static void vty_show_ip_route_summary(struct vty *vty, "fib", fib_cnt[i]); json_object_int_add(json_route_type, "rib", rib_cnt[i]); + + json_object_int_add(json_route_type, + "fibOffLoaded", + offload_cnt[i]); + json_object_int_add(json_route_type, + "fibTrapped", + trap_cnt[i]); json_object_string_add( json_route_type, "type", zebra_route_string(i)); |
