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 | 6 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 30 | ||||
| -rw-r--r-- | zebra/zebra_router.c | 10 | ||||
| -rw-r--r-- | zebra/zebra_router.h | 5 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 47 |
7 files changed, 119 insertions, 15 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 4dc8c2a6eb..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) { diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b688704962..569b23573c 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1821,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) { @@ -1899,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); @@ -2067,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_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)); |
