diff options
46 files changed, 1220 insertions, 497 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e8a364050a..61bc0ade65 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1 +1,12 @@ +# Following revs are all whitespace changes; use with +# git blame --ignore-revs-file .git-blame-ignore-revs <...> +# or to make it permanent +# git config blame.ignoreRevsFile .git-blame-ignore-revs +701a01920eee5431d2052aad92aefbdf50ac2139 +bf2394f08bdc91a6cbd3784a1bfa3af3247bb06f +0157c327715ca367d13b7f02b2981f3484ccdeeb +787e762445d50ca5b52fafcf8dd6de08ab90916f +ac2914d3261a78cf78eec7a6e20ebbe42bb57150 +ac4d0be5874fafd14212d6007fff7495edc9b152 d62a17aedeb0eebdba98238874bb13d62c48dbf9 +c14777c6bfd0a446c85243d3a9835054a259c276 diff --git a/.ignore-revs b/.ignore-revs deleted file mode 100644 index 3cf4ed9f54..0000000000 --- a/.ignore-revs +++ /dev/null @@ -1,10 +0,0 @@ -# Following revs are all whitespace changes; use with -# git blame --ignore-revs-file .ignore-revs <...> -701a01920eee5431d2052aad92aefbdf50ac2139 -bf2394f08bdc91a6cbd3784a1bfa3af3247bb06f -0157c327715ca367d13b7f02b2981f3484ccdeeb -787e762445d50ca5b52fafcf8dd6de08ab90916f -ac2914d3261a78cf78eec7a6e20ebbe42bb57150 -ac4d0be5874fafd14212d6007fff7495edc9b152 -d62a17aedeb0eebdba98238874bb13d62c48dbf9 -c14777c6bfd0a446c85243d3a9835054a259c276 diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index 0308a30d54..3162579688 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -507,14 +507,16 @@ DEFUN(no_as_path, no_bgp_as_path_cmd, /* Lookup asfilter. */ asfilter = as_filter_lookup(aslist, regstr, type); - XFREE(MTYPE_TMP, regstr); bgp_regex_free(regex); if (asfilter == NULL) { - vty_out(vty, "\n"); + vty_out(vty, "Regex entered %s does not exist\n", regstr); + XFREE(MTYPE_TMP, regstr); return CMD_WARNING_CONFIG_FAILED; } + XFREE(MTYPE_TMP, regstr); + as_list_filter_delete(aslist, asfilter); return CMD_SUCCESS; diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 85c0eccc26..aa98515c3f 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -31,8 +31,7 @@ #define BGP_TIMER_OFF(T) \ do { \ - if (T) \ - THREAD_TIMER_OFF(T); \ + THREAD_TIMER_OFF(T); \ } while (0) #define BGP_EVENT_ADD(P, E) \ diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c index b9fff124df..551bdb0c2b 100644 --- a/bgpd/bgp_nb.c +++ b/bgpd/bgp_nb.c @@ -30,8 +30,8 @@ const struct frr_yang_module_info frr_bgp_info = { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp", .cbs = { .cli_show = cli_show_router_bgp, - .create = bgp_create, - .destroy = bgp_destroy, + .create = bgp_router_create, + .destroy = bgp_router_destroy, } }, { diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h index 097b40d7b7..341666c7ed 100644 --- a/bgpd/bgp_nb.h +++ b/bgpd/bgp_nb.h @@ -26,8 +26,8 @@ extern const struct frr_yang_module_info frr_bgp_info; /* prototypes */ -int bgp_create(struct nb_cb_create_args *args); -int bgp_destroy(struct nb_cb_destroy_args *args); +int bgp_router_create(struct nb_cb_create_args *args); +int bgp_router_destroy(struct nb_cb_destroy_args *args); int bgp_global_local_as_modify(struct nb_cb_modify_args *args); int bgp_global_router_id_modify(struct nb_cb_modify_args *args); int bgp_global_router_id_destroy(struct nb_cb_destroy_args *args); diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index ba7c5714bb..f01325577c 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -62,7 +62,7 @@ int routing_control_plane_protocols_name_validate( * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp */ -int bgp_create(struct nb_cb_create_args *args) +int bgp_router_create(struct nb_cb_create_args *args) { const struct lyd_node *vrf_dnode; struct bgp *bgp; @@ -107,8 +107,8 @@ int bgp_create(struct nb_cb_create_args *args) if (ret == BGP_ERR_INSTANCE_MISMATCH) { snprintf( args->errmsg, args->errmsg_len, - "BGP instance name and AS number mismatch\nBGP instance is already running; AS is %u", - as); + "BGP instance name and AS number mismatch\nBGP instance is already running; AS is %u, input-as %u", + bgp->as, as); return NB_ERR_INCONSISTENCY; } @@ -132,7 +132,7 @@ int bgp_create(struct nb_cb_create_args *args) return NB_OK; } -int bgp_destroy(struct nb_cb_destroy_args *args) +int bgp_router_destroy(struct nb_cb_destroy_args *args) { struct bgp *bgp; @@ -140,6 +140,9 @@ int bgp_destroy(struct nb_cb_destroy_args *args) case NB_EV_VALIDATE: bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + if (bgp->l3vni) { snprintf(args->errmsg, args->errmsg_len, "Please unconfigure l3vni %u", bgp->l3vni); @@ -186,16 +189,42 @@ int bgp_global_local_as_modify(struct nb_cb_modify_args *args) { struct bgp *bgp; as_t as; + const struct lyd_node *vrf_dnode; + const char *vrf_name; + const char *name = NULL; + enum bgp_instance_type inst_type; + int ret; + bool is_view_inst = false; switch (args->event) { case NB_EV_VALIDATE: as = yang_dnode_get_uint32(args->dnode, NULL); - bgp = nb_running_get_entry_non_rec(args->dnode, NULL, false); - if (bgp && bgp->as != as) { - snprintf(args->errmsg, args->errmsg_len, - "BGP instance is already running; AS is %u", - bgp->as); + inst_type = BGP_INSTANCE_TYPE_DEFAULT; + + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + + if (strmatch(vrf_name, VRF_DEFAULT_NAME)) { + name = NULL; + } else { + name = vrf_name; + inst_type = BGP_INSTANCE_TYPE_VRF; + } + + is_view_inst = yang_dnode_get_bool(args->dnode, + "../instance-type-view"); + if (is_view_inst) + inst_type = BGP_INSTANCE_TYPE_VIEW; + + ret = bgp_lookup_by_as_name_type(&bgp, &as, name, inst_type); + if (ret == BGP_ERR_INSTANCE_MISMATCH) { + snprintf( + args->errmsg, args->errmsg_len, + "BGP instance name and AS number mismatch\nBGP instance is already running; input-as %u", + as); + return NB_ERR_VALIDATION; } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 09cc775d47..968cda3f10 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3960,8 +3960,7 @@ static void bgp_route_map_mark_update(const char *rmap_name) /* If new update is received before the current timer timed out, * turn it off and start a new timer. */ - if (bm->t_rmap_update != NULL) - THREAD_OFF(bm->t_rmap_update); + THREAD_OFF(bm->t_rmap_update); /* rmap_update_timer of 0 means don't do route updates */ if (bm->rmap_update_timer) { diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index d2e563b237..1685f98181 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -795,17 +795,14 @@ static void update_subgroup_delete(struct update_subgroup *subgrp) if (subgrp->update_group) UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted); - if (subgrp->t_merge_check) - THREAD_OFF(subgrp->t_merge_check); + THREAD_OFF(subgrp->t_merge_check); - if (subgrp->t_coalesce) - THREAD_TIMER_OFF(subgrp->t_coalesce); + THREAD_TIMER_OFF(subgrp->t_coalesce); bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp)); subgroup_clear_table(subgrp); - if (subgrp->t_coalesce) - THREAD_TIMER_OFF(subgrp->t_coalesce); + THREAD_TIMER_OFF(subgrp->t_coalesce); sync_delete(subgrp); if (BGP_DEBUG(update_groups, UPDATE_GROUPS) && subgrp->update_group) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 6b04168304..c8a3c28523 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1222,9 +1222,6 @@ DEFUN_YANG_NOSH(router_bgp, vty_out(vty, "%% Please specify ASN and VRF\n"); return CMD_WARNING_CONFIG_FAILED; } - /* unset the auto created flag as the user config is now present - */ - UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp", "bgp", VRF_DEFAULT_NAME); @@ -1239,6 +1236,7 @@ DEFUN_YANG_NOSH(router_bgp, NB_OP_MODIFY, "true"); } + nb_cli_pending_commit_check(vty); ret = nb_cli_apply_changes(vty, base_xpath); if (ret == CMD_SUCCESS) { VTY_PUSH_XPATH(BGP_NODE, base_xpath); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 30566b2c16..3e2ca70a02 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3238,12 +3238,10 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, return bgp_check_main_socket(create, bgp); } -/* Called from VTY commands. */ -int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, - enum bgp_instance_type inst_type) +int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name, + enum bgp_instance_type inst_type) { struct bgp *bgp; - struct vrf *vrf = NULL; /* Multiple instance check. */ if (name) @@ -3251,7 +3249,6 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, else bgp = bgp_get_default(); - /* Already exists. */ if (bgp) { if (bgp->as != *as) { *as = bgp->as; @@ -3262,6 +3259,27 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, *bgp_val = bgp; return BGP_SUCCESS; } + *bgp_val = NULL; + + return BGP_SUCCESS; +} + +/* Called from VTY commands. */ +int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, + enum bgp_instance_type inst_type) +{ + struct bgp *bgp; + struct vrf *vrf = NULL; + int ret = 0; + + ret = bgp_lookup_by_as_name_type(bgp_val, as, name, inst_type); + switch (ret) { + case BGP_ERR_INSTANCE_MISMATCH: + return ret; + case BGP_SUCCESS: + if (*bgp_val) + return ret; + } bgp = bgp_create(as, name, inst_type); if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 3e3c6fc9e3..00f1d5acc9 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -2181,6 +2181,9 @@ extern struct peer *peer_new(struct bgp *bgp); extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, const char *ip_str, bool use_json); +extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, + const char *name, + enum bgp_instance_type inst_type); /* Hooks */ DECLARE_HOOK(peer_status_changed, (struct peer * peer), (peer)) diff --git a/configure.ac b/configure.ac index 3cc74c4110..8e86ba87ff 100755 --- a/configure.ac +++ b/configure.ac @@ -139,6 +139,13 @@ AC_ARG_WITH([yangmodelsdir], [AS_HELP_STRING([--with-yangmodelsdir=DIR], [yang m ]) AC_SUBST([yangmodelsdir]) +AC_ARG_WITH([vici-socket], [AS_HELP_STRING([--with-vici-socket=PATH], [vici-socket (/var/run/charon.vici)])], [ + vici_socket="$withval" +], [ + vici_socket="/var/run/charon.vici" +]) +AC_DEFINE_UNQUOTED([VICI_SOCKET], ["$vici_socket"], [StrongSWAN vici socket path]) + AC_ARG_ENABLE(tcmalloc, AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]), [case "${enableval}" in @@ -2512,6 +2519,7 @@ group for vty sockets : ${enable_vty_group} config file mask : ${enable_configfile_mask} log file mask : ${enable_logfile_mask} zebra protobuf enabled : ${enable_protobuf:-no} +vici socket path : ${vici_socket} The above user and group must have read/write access to the state file directory and to the config files in the config file directory." diff --git a/doc/manpages/frr-zebra.rst b/doc/manpages/frr-zebra.rst index cfb368bf44..722b011ecd 100644 --- a/doc/manpages/frr-zebra.rst +++ b/doc/manpages/frr-zebra.rst @@ -25,10 +25,6 @@ OPTIONS available for the |DAEMON| command: Runs in batch mode, zebra parses its config and exits. -.. option:: -k, --keep_kernel - - On startup, don't delete self inserted routes. - .. option:: -s, --nl-bufsize <netlink-buffer-size> Set netlink receive buffer size. There are cases where zebra daemon can't handle flood of netlink messages from kernel. If you ever see "recvmsg overrun" messages in zebra log, you are in trouble. diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 0fd33eace8..ee06578b7c 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -380,6 +380,10 @@ options to the configuration script. Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR YANG modules will be installed here. +.. option:: --with-vici-socket <path> + + Set StrongSWAN vici interface socket path [/var/run/charon.vici]. + Python dependency, documentation and tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 9ef4e86237..2f3f347423 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -331,8 +331,7 @@ int eigrp_if_down(struct eigrp_interface *ei) return 0; /* Shutdown packet reception and sending */ - if (ei->t_hello) - THREAD_OFF(ei->t_hello); + THREAD_OFF(ei->t_hello); eigrp_if_stream_unset(ei); diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c index c15b59a8cf..8360dfc59e 100644 --- a/isisd/isis_ldp_sync.c +++ b/isisd/isis_ldp_sync.c @@ -300,10 +300,7 @@ void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit) if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED && ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) { - if (ldp_sync_info->t_holddown != NULL) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; - } + THREAD_TIMER_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; isis_ldp_sync_set_if_metric(circuit, true); } @@ -326,8 +323,7 @@ void isis_ldp_sync_if_remove(struct isis_circuit *circuit, bool remove) ils_debug("ldp_sync: remove if %s", circuit->interface ? circuit->interface->name : ""); - if (ldp_sync_info->t_holddown) - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); + THREAD_TIMER_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; isis_ldp_sync_set_if_metric(circuit, true); if (remove) { diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index d5f4c605c4..24228ed701 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -2075,7 +2075,6 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args) struct interface *ifp; struct vrf *vrf; const char *area_tag, *ifname, *vrfname; - struct isis *isis = NULL; if (args->event == NB_EV_VALIDATE) { /* libyang doesn't like relative paths across module boundaries @@ -2091,11 +2090,7 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args) if (!ifp) return NB_OK; - isis = isis_lookup_by_vrfid(ifp->vrf_id); - if (isis == NULL) - return NB_ERR_VALIDATION; - - circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list); + circuit = circuit_scan_by_ifp(ifp); area_tag = yang_dnode_get_string(args->dnode, NULL); if (circuit && circuit->area && circuit->area->area_tag && strcmp(circuit->area->area_tag, area_tag)) { diff --git a/lib/ldp_sync.c b/lib/ldp_sync.c index 5dd045d88d..9657f0b1df 100644 --- a/lib/ldp_sync.c +++ b/lib/ldp_sync.c @@ -79,10 +79,8 @@ bool ldp_sync_if_down(struct ldp_sync_info *ldp_sync_info) * update state */ if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) { - if (ldp_sync_info->t_holddown != NULL) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; - } + THREAD_TIMER_OFF(ldp_sync_info->t_holddown); + if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP) ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c index 4e74714489..acb208e5e7 100644 --- a/lib/spf_backoff.c +++ b/lib/spf_backoff.c @@ -132,7 +132,6 @@ static int spf_backoff_holddown_elapsed(struct thread *thread) { struct spf_backoff *backoff = THREAD_ARG(thread); - backoff->t_holddown = NULL; THREAD_TIMER_OFF(backoff->t_timetolearn); timerclear(&backoff->first_event_time); backoff->state = SPF_BACKOFF_QUIET; diff --git a/nhrpd/README.nhrpd b/nhrpd/README.nhrpd index 569b3f4463..8bb5f69bea 100644 --- a/nhrpd/README.nhrpd +++ b/nhrpd/README.nhrpd @@ -126,7 +126,8 @@ Integration with strongSwan Contrary to opennhrp, Quagga/NHRP has tight integration with IKE daemon. Currently strongSwan is supported using the VICI protocol. strongSwan -is connected using UNIX socket (hardcoded now as /var/run/charon.vici). +is connected using UNIX socket (default /var/run/charon.vici use configure +argument --with-vici-socket= to change). Thus nhrpd needs to be run as user that can open that file. Currently, you will need patched strongSwan. The working tree is at: diff --git a/nhrpd/vici.c b/nhrpd/vici.c index 2dc05a4aa7..86554f53dc 100644 --- a/nhrpd/vici.c +++ b/nhrpd/vici.c @@ -478,7 +478,7 @@ static int vici_reconnect(struct thread *t) if (vici->fd >= 0) return 0; - fd = sock_open_unix("/var/run/charon.vici"); + fd = sock_open_unix(VICI_SOCKET); if (fd < 0) { debugf(NHRP_DEBUG_VICI, "%s: failure connecting VICI socket: %s", __func__, diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c index da390e3c70..d4f0dc953c 100644 --- a/ospfclient/ospf_apiclient.c +++ b/ospfclient/ospf_apiclient.c @@ -49,6 +49,7 @@ #include "ospfd/ospf_route.h" #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_api.h" +#include "ospfd/ospf_errors.h" #include "ospf_apiclient.h" @@ -564,15 +565,25 @@ static void ospf_apiclient_handle_lsa_update(struct ospf_apiclient *oclient, { struct msg_lsa_change_notify *cn; struct lsa_header *lsa; - int lsalen; + void *p; + uint16_t lsalen; cn = (struct msg_lsa_change_notify *)STREAM_DATA(msg->s); /* Extract LSA from message */ lsalen = ntohs(cn->data.length); - lsa = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); + if (lsalen > OSPF_MAX_LSA_SIZE) { + flog_warn( + EC_OSPF_LARGE_LSA, + "%s: message received size: %d is greater than a LSA size: %d", + __func__, lsalen, OSPF_MAX_LSA_SIZE); + return; + } + + p = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); - memcpy(lsa, &(cn->data), lsalen); + memcpy(p, &(cn->data), lsalen); + lsa = p; /* Invoke registered update callback function */ if (oclient->update_notify) { @@ -581,7 +592,7 @@ static void ospf_apiclient_handle_lsa_update(struct ospf_apiclient *oclient, } /* free memory allocated by ospf apiclient library */ - XFREE(MTYPE_OSPF_APICLIENT, lsa); + XFREE(MTYPE_OSPF_APICLIENT, p); } static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient, @@ -589,15 +600,25 @@ static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient, { struct msg_lsa_change_notify *cn; struct lsa_header *lsa; - int lsalen; + void *p; + uint16_t lsalen; cn = (struct msg_lsa_change_notify *)STREAM_DATA(msg->s); /* Extract LSA from message */ lsalen = ntohs(cn->data.length); - lsa = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); + if (lsalen > OSPF_MAX_LSA_SIZE) { + flog_warn( + EC_OSPF_LARGE_LSA, + "%s: message received size: %d is greater than a LSA size: %d", + __func__, lsalen, OSPF_MAX_LSA_SIZE); + return; + } + + p = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); - memcpy(lsa, &(cn->data), lsalen); + memcpy(p, &(cn->data), lsalen); + lsa = p; /* Invoke registered update callback function */ if (oclient->delete_notify) { @@ -606,7 +627,7 @@ static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient, } /* free memory allocated by ospf apiclient library */ - XFREE(MTYPE_OSPF_APICLIENT, lsa); + XFREE(MTYPE_OSPF_APICLIENT, p); } static void ospf_apiclient_msghandle(struct ospf_apiclient *oclient, diff --git a/ospfd/ospf_gr_helper.c b/ospfd/ospf_gr_helper.c index a7b20d1f07..616013fb9e 100644 --- a/ospfd/ospf_gr_helper.c +++ b/ospfd/ospf_gr_helper.c @@ -50,26 +50,26 @@ #include "ospfd/ospf_ism.h" #include "ospfd/ospf_gr_helper.h" -const char *ospf_exit_reason_desc[] = { +static const char * const ospf_exit_reason_desc[] = { "Unknown reason", "Helper inprogress", "Topology Change", - "Grace timer expairy", + "Grace timer expiry", "Successful graceful restart", }; -const char *ospf_restart_reason_desc[] = { +static const char * const ospf_restart_reason_desc[] = { "Unknown restart", "Software restart", "Software reload/upgrade", "Switch to redundant control processor", }; -const char *ospf_rejected_reason_desc[] = { +static const char * const ospf_rejected_reason_desc[] = { "Unknown reason", "Helper support disabled", "Neighbour is not in FULL state", - "Supports only planned restart but received for unplanned", + "Supports only planned restart but received unplanned", "Topo change due to change in lsa rxmt list", "LSA age is more than Grace interval", }; @@ -118,6 +118,39 @@ static void ospf_enable_rtr_hash_destroy(struct ospf *ospf) } /* + * GR exit reason strings + */ +const char *ospf_exit_reason2str(unsigned int reason) +{ + if (reason < array_size(ospf_exit_reason_desc)) + return(ospf_exit_reason_desc[reason]); + else + return "Invalid reason"; +} + +/* + * GR restart reason strings + */ +const char *ospf_restart_reason2str(unsigned int reason) +{ + if (reason < array_size(ospf_restart_reason_desc)) + return(ospf_restart_reason_desc[reason]); + else + return "Invalid reason"; +} + +/* + * GR rejected reason strings + */ +const char *ospf_rejected_reason2str(unsigned int reason) +{ + if (reason < array_size(ospf_rejected_reason_desc)) + return(ospf_rejected_reason_desc[reason]); + else + return "Invalid reason"; +} + +/* * Initialize GR helper config data structures. * * OSPF @@ -200,12 +233,38 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa, lsah = (struct lsa_header *)lsa->data; - length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE; + length = ntohs(lsah->length); + + /* Check LSA len */ + if (length <= OSPF_LSA_HEADER_SIZE) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s: Malformed packet: Invalid LSA len:%d", + __func__, length); + return OSPF_GR_FAILURE; + } + + length -= OSPF_LSA_HEADER_SIZE; for (tlvh = TLV_HDR_TOP(lsah); sum < length; tlvh = TLV_HDR_NEXT(tlvh)) { + + /* Check TLV len against overall LSA */ + if (sum + TLV_SIZE(tlvh) > length) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s: Malformed packet: Invalid TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + switch (ntohs(tlvh->type)) { case GRACE_PERIOD_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_graceperiod)) { + zlog_debug("%s: Malformed packet: Invalid grace TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + grace_period = (struct grace_tlv_graceperiod *)tlvh; *interval = ntohl(grace_period->interval); sum += TLV_SIZE(tlvh); @@ -216,6 +275,13 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa, return OSPF_GR_FAILURE; break; case RESTART_REASON_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_reason)) { + zlog_debug("%s: Malformed packet: Invalid reason TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + gr_reason = (struct grace_tlv_restart_reason *)tlvh; *reason = gr_reason->reason; sum += TLV_SIZE(tlvh); @@ -224,6 +290,13 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa, return OSPF_GR_FAILURE; break; case RESTARTER_IP_ADDR_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_addr)) { + zlog_debug("%s: Malformed packet: Invalid addr TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + restart_addr = (struct grace_tlv_restart_addr *)tlvh; addr->s_addr = restart_addr->addr.s_addr; sum += TLV_SIZE(tlvh); @@ -306,7 +379,8 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa, zlog_debug( "%s, Grace LSA received from %s, grace interval:%u, restartreason :%s", __PRETTY_FUNCTION__, inet_ntoa(restart_addr), - grace_interval, ospf_restart_reason_desc[restart_reason]); + grace_interval, + ospf_restart_reason2str(restart_reason)); /* Incase of broadcast links, if RESTARTER is DR_OTHER, * grace LSA might be received from DR, so need to get @@ -524,7 +598,7 @@ void ospf_helper_handle_topo_chg(struct ospf *ospf, struct ospf_lsa *lsa) if (!ospf->active_restarter_cnt) return; - /* Topo change not required to be hanlded if strict + /* Topo change not required to be handled if strict * LSA check is disbaled for this router. */ if (!ospf->strict_lsa_check) @@ -598,7 +672,7 @@ void ospf_gr_helper_exit(struct ospf_neighbor *nbr, if (IS_DEBUG_OSPF_GR_HELPER) zlog_debug("%s, Exiting from HELPER support to %s, due to %s", __PRETTY_FUNCTION__, inet_ntoa(nbr->src), - ospf_exit_reason_desc[reason]); + ospf_exit_reason2str(reason)); /* Reset helper status*/ nbr->gr_helper_info.gr_helper_status = OSPF_GR_NOT_HELPER; @@ -929,14 +1003,36 @@ static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa) lsah = (struct lsa_header *)lsa->data; - length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE; + length = ntohs(lsah->length); + + if (length <= OSPF_LSA_HEADER_SIZE) { + vty_out(vty, "%% Invalid LSA length: %d\n", length); + return; + } + + length -= OSPF_LSA_HEADER_SIZE; vty_out(vty, " TLV info:\n"); for (tlvh = TLV_HDR_TOP(lsah); sum < length; tlvh = TLV_HDR_NEXT(tlvh)) { + /* Check TLV len */ + if (sum + TLV_SIZE(tlvh) > length) { + vty_out(vty, "%% Invalid TLV length: %zu\n", + TLV_SIZE(tlvh)); + return; + } + switch (ntohs(tlvh->type)) { case GRACE_PERIOD_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_graceperiod)) { + vty_out(vty, + "%% Invalid grace TLV length %zu\n", + TLV_SIZE(tlvh)); + return; + } + gracePeriod = (struct grace_tlv_graceperiod *)tlvh; sum += TLV_SIZE(tlvh); @@ -944,13 +1040,29 @@ static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa) ntohl(gracePeriod->interval)); break; case RESTART_REASON_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_reason)) { + vty_out(vty, + "%% Invalid reason TLV length %zu\n", + TLV_SIZE(tlvh)); + return; + } + grReason = (struct grace_tlv_restart_reason *)tlvh; sum += TLV_SIZE(tlvh); vty_out(vty, " Restart reason:%s\n", - ospf_restart_reason_desc[grReason->reason]); + ospf_restart_reason2str(grReason->reason)); break; case RESTARTER_IP_ADDR_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_addr)) { + vty_out(vty, + "%% Invalid addr TLV length %zu\n", + TLV_SIZE(tlvh)); + return; + } + restartAddr = (struct grace_tlv_restart_addr *)tlvh; sum += TLV_SIZE(tlvh); @@ -958,6 +1070,9 @@ static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa) inet_ntoa(restartAddr->addr)); break; default: + vty_out(vty, " Unknown TLV type %d\n", + ntohs(tlvh->type)); + break; } } diff --git a/ospfd/ospf_gr_helper.h b/ospfd/ospf_gr_helper.h index 4e83028fe6..c355bb4f3d 100644 --- a/ospfd/ospf_gr_helper.h +++ b/ospfd/ospf_gr_helper.h @@ -152,9 +152,9 @@ struct advRtr { #define OSPF_GR_FAILURE 0 #define OSPF_GR_INVALID -1 -extern const char *ospf_exit_reason_desc[]; -extern const char *ospf_restart_reason_desc[]; -extern const char *ospf_rejected_reason_desc[]; +const char *ospf_exit_reason2str(unsigned int reason); +const char *ospf_restart_reason2str(unsigned int reason); +const char *ospf_rejected_reason2str(unsigned int reason); extern void ospf_gr_helper_init(struct ospf *ospf); extern void ospf_gr_helper_stop(struct ospf *ospf); diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index cdb0eae2c4..96fa04b588 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -274,10 +274,7 @@ void ospf_ldp_sync_ldp_fail(struct interface *ifp) if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED && ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) { - if (ldp_sync_info->t_holddown != NULL) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; - } + THREAD_TIMER_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; ospf_if_recalculate_output_cost(ifp); } @@ -340,8 +337,7 @@ void ospf_ldp_sync_if_remove(struct interface *ifp, bool remove) * restore cost */ ols_debug("ldp_sync: Removed from if %s", ifp->name); - if (ldp_sync_info->t_holddown) - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); + THREAD_TIMER_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; ospf_if_recalculate_output_cost(ifp); if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG)) diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 3a1547978a..28aec41eba 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -201,7 +201,6 @@ int ospf_sock_init(struct ospf *ospf) flog_err(EC_LIB_SOCKET, "Can't set IP_HDRINCL option for fd %d: %s", ospf_sock, safe_strerror(errno)); - close(ospf_sock); break; } #elif defined(IPTOS_PREC_INTERNETCONTROL) @@ -213,7 +212,6 @@ int ospf_sock_init(struct ospf *ospf) flog_err(EC_LIB_SOCKET, "can't set sockopt IP_TOS %d to socket %d: %s", tos, ospf_sock, safe_strerror(errno)); - close(ospf_sock); /* Prevent sd leak. */ break; } #else /* !IPTOS_PREC_INTERNETCONTROL */ diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 63191d5cb5..8e5cb5bb36 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -2486,20 +2486,25 @@ static void ospfTrapVirtNbrStateChange(struct ospf_neighbor *on) static int ospf_snmp_nsm_change(struct ospf_neighbor *nbr, int next_state, int old_state) { - /* Terminal state or regression */ - if ((next_state == NSM_Full) || (next_state == NSM_TwoWay) - || (next_state < old_state)) { - /* ospfVirtNbrStateChange */ - if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK) - ospfTrapVirtNbrStateChange(nbr); - /* ospfNbrStateChange trap */ - else - /* To/From FULL, only managed by DR */ - if (((next_state != NSM_Full) - && (nbr->state != NSM_Full)) - || (nbr->oi->state == ISM_DR)) - ospfTrapNbrStateChange(nbr); - } + /* Transition to/from state Full should be handled only by + * DR when in Broadcast or Non-Brodcast Multi-Access networks + */ + if ((next_state == NSM_Full || old_state == NSM_Full) + && (nbr->oi->state != ISM_DR) + && (nbr->oi->type == OSPF_IFTYPE_BROADCAST + || nbr->oi->type == OSPF_IFTYPE_NBMA)) + return 0; + + /* State progression to non-terminal state */ + if (next_state > old_state && next_state != NSM_Full + && next_state != NSM_TwoWay) + return 0; + + if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK) + ospfTrapVirtNbrStateChange(nbr); + else + ospfTrapNbrStateChange(nbr); + return 0; } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 1a9ad69ed3..5c82e11393 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -5132,9 +5132,8 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, " Graceful Restart grace period time: %d (seconds).\n", nbr->gr_helper_info.recvd_grace_period); vty_out(vty, " Graceful Restart reason: %s.\n", - ospf_restart_reason_desc - [nbr->gr_helper_info - .gr_restart_reason]); + ospf_restart_reason2str( + nbr->gr_helper_info.gr_restart_reason)); } else { vty_out(vty, " Graceful Restart HELPER Status : None\n"); @@ -5143,15 +5142,14 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, if (nbr->gr_helper_info.rejected_reason != OSPF_HELPER_REJECTED_NONE) vty_out(vty, " Helper rejected reason: %s.\n", - ospf_rejected_reason_desc - [nbr->gr_helper_info.rejected_reason]); + ospf_rejected_reason2str( + nbr->gr_helper_info.rejected_reason)); if (nbr->gr_helper_info.helper_exit_reason != OSPF_GR_HELPER_EXIT_NONE) vty_out(vty, " Last helper exit reason: %s.\n\n", - ospf_exit_reason_desc - [nbr->gr_helper_info - .helper_exit_reason]); + ospf_exit_reason2str( + nbr->gr_helper_info.helper_exit_reason)); else vty_out(vty, "\n"); } else { @@ -5165,25 +5163,24 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, nbr->gr_helper_info.recvd_grace_period); json_object_string_add( json_neigh, "grRestartReason", - ospf_restart_reason_desc - [nbr->gr_helper_info - .gr_restart_reason]); + ospf_restart_reason2str( + nbr->gr_helper_info.gr_restart_reason)); } if (nbr->gr_helper_info.rejected_reason != OSPF_HELPER_REJECTED_NONE) json_object_string_add( json_neigh, "helperRejectReason", - ospf_rejected_reason_desc - [nbr->gr_helper_info.rejected_reason]); + ospf_rejected_reason2str( + nbr->gr_helper_info.rejected_reason)); if (nbr->gr_helper_info.helper_exit_reason != OSPF_GR_HELPER_EXIT_NONE) json_object_string_add( json_neigh, "helperExitReason", - ospf_exit_reason_desc - [nbr->gr_helper_info - .helper_exit_reason]); + ospf_exit_reason2str( + nbr->gr_helper_info + .helper_exit_reason)); } ospf_bfd_show_info(vty, nbr->bfd_info, json_neigh, use_json, 0); @@ -8135,12 +8132,25 @@ DEFUN (ip_ospf_area, ospf = ospf_lookup_instance(instance); if (instance && ospf == NULL) { + /* + * At this point we know we have received + * an instance and there is no ospf instance + * associated with it. This means we are + * in a situation where we have an + * ospf command that is setup for a different + * process(instance). We need to safely + * remove the command from ourselves and + * allow the other instance(process) handle + * the configuration command. + */ params = IF_DEF_PARAMS(ifp); if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { UNSET_IF_PARAM(params, if_area); ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - ospf_interface_area_unset(ospf, ifp); - ospf->if_ospf_cli_count--; + if (ospf) { + ospf_interface_area_unset(ospf, ifp); + ospf->if_ospf_cli_count--; + } } return CMD_NOT_MY_INSTANCE; } @@ -8232,7 +8242,7 @@ DEFUN (no_ip_ospf_area, else ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance && ospf == NULL) return CMD_NOT_MY_INSTANCE; argv_find(argv, argc, "area", &idx); @@ -8262,8 +8272,11 @@ DEFUN (no_ip_ospf_area, ospf_if_update_params((ifp), (addr)); } - ospf_interface_area_unset(ospf, ifp); - ospf->if_ospf_cli_count--; + if (ospf) { + ospf_interface_area_unset(ospf, ifp); + ospf->if_ospf_cli_count--; + } + return CMD_SUCCESS; } @@ -9292,7 +9305,7 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) { vty_out(vty, " Last Helper exit Reason :%s\n", - ospf_exit_reason_desc[ospf->last_exit_reason]); + ospf_exit_reason2str(ospf->last_exit_reason)); } if (ospf->active_restarter_cnt) @@ -9321,7 +9334,7 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) json_object_string_add( json_vrf, "LastExitReason", - ospf_exit_reason_desc[ospf->last_exit_reason]); + ospf_exit_reason2str(ospf->last_exit_reason)); if (ospf->active_restarter_cnt) json_object_int_add(json_vrf, "activeRestarterCnt", @@ -9386,9 +9399,9 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, .t_grace_timer)); vty_out(vty, " Graceful Restart reason: %s.\n\n", - ospf_restart_reason_desc - [nbr->gr_helper_info - .gr_restart_reason]); + ospf_restart_reason2str( + nbr->gr_helper_info + .gr_restart_reason)); cnt++; } else { json_neigh = json_object_new_object(); @@ -9416,9 +9429,9 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, .t_grace_timer)); json_object_string_add( json_neigh, "restartReason", - ospf_restart_reason_desc - [nbr->gr_helper_info - .gr_restart_reason]); + ospf_restart_reason2str( + nbr->gr_helper_info + .gr_restart_reason)); json_object_object_add( json_neighbors, inet_ntoa(nbr->src), diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 1c9005588f..f542b2eafa 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -117,8 +117,7 @@ static int pim_g2rp_list_compare(struct bsm_rpinfo *node1, static void pim_free_bsrp_node(struct bsm_rpinfo *bsrp_info) { - if (bsrp_info->g2rp_timer) - THREAD_OFF(bsrp_info->g2rp_timer); + THREAD_OFF(bsrp_info->g2rp_timer); XFREE(MTYPE_PIM_BSRP_NODE, bsrp_info); } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 212c77c039..b2971e5f1f 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -950,14 +950,44 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr, pim_ifchannel_ifjoin_handler(ch, pim_ifp); break; case PIM_IFJOIN_PRUNE_PENDING: + /* + * Transitions from Prune-Pending State (Receive Join) + * RFC 7761 Sec 4.5.2: + * The (S,G) downstream state machine on interface I + * transitions to the Join state. The Prune-Pending Timer is + * canceled (without triggering an expiry event). The + * Expiry Timer (ET) is restarted and is then set to the + * maximum of its current value and the HoldTime from the + * triggering Join/Prune message. + */ THREAD_OFF(ch->t_ifjoin_prune_pending_timer); - if (source_flags & PIM_ENCODE_RPT_BIT) { + + /* Check if SGRpt join Received */ + if ((source_flags & PIM_ENCODE_RPT_BIT) + && (sg->src.s_addr != INADDR_ANY)) { + /* + * Transitions from Prune-Pending State (Rcv SGRpt Join) + * RFC 7761 Sec 4.5.3: + * The (S,G,rpt) downstream state machine on interface + * I transitions to the NoInfo state.The ET and PPT are + * cancelled. + */ THREAD_OFF(ch->t_ifjoin_expiry_timer); pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO); - } else { - pim_ifchannel_ifjoin_handler(ch, pim_ifp); + return; } + + pim_ifchannel_ifjoin_handler(ch, pim_ifp); + + if (ch->t_ifjoin_expiry_timer) { + unsigned long remain = thread_timer_remain_second( + ch->t_ifjoin_expiry_timer); + + if (remain > holdtime) + return; + } + break; case PIM_IFJOIN_PRUNE_TMP: break; @@ -1034,7 +1064,14 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, /* nothing to do */ break; case PIM_IFJOIN_JOIN: - THREAD_OFF(ch->t_ifjoin_expiry_timer); + /* + * The (S,G) downstream state machine on interface I + * transitions to the Prune-Pending state. The + * Prune-Pending Timer is started. It is set to the + * J/P_Override_Interval(I) if the router has more than one + * neighbor on that interface; otherwise, it is set to zero, + * causing it to expire immediately. + */ pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_PRUNE_PENDING); diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 04ece6dbb0..d4d47377bd 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -804,9 +804,7 @@ void igmp_group_delete(struct igmp_group *group) igmp_source_delete(src); } - if (group->t_group_query_retransmit_timer) { - THREAD_OFF(group->t_group_query_retransmit_timer); - } + THREAD_OFF(group->t_group_query_retransmit_timer); group_timer_off(group); igmp_group_count_decr(group->group_igmp_sock); diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 3a88de2070..f54d5bf9bf 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -173,6 +173,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, uint8_t *pastend; int remain; int group; + struct pim_ifchannel *child = NULL; + struct listnode *ch_node, *nch_node; buf = tlv_buf; pastend = tlv_buf + tlv_buf_size; @@ -337,9 +339,24 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, */ sg_ch = pim_ifchannel_find(ifp, &sg); + if (!sg_ch) + continue; + + /* (*,G) prune received */ + for (ALL_LIST_ELEMENTS(sg_ch->sources, ch_node, + nch_node, child)) { + if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) { + if (child->ifjoin_state + == PIM_IFJOIN_PRUNE_PENDING_TMP) + THREAD_OFF( + child->t_ifjoin_prune_pending_timer); + PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); + child->ifjoin_state = PIM_IFJOIN_NOINFO; + } + } + /* Received SG-RPT Prune delete oif from specific S,G */ - if (starg_ch && sg_ch - && (msg_source_flags & PIM_RPT_BIT_MASK) + if (starg_ch && (msg_source_flags & PIM_RPT_BIT_MASK) && !(msg_source_flags & PIM_WILDCARD_BIT_MASK)) { struct pim_upstream *up = sg_ch->upstream; PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags); diff --git a/ripngd/ripng_nb_config.c b/ripngd/ripng_nb_config.c index 85f378bc9e..25bf65f7aa 100644 --- a/ripngd/ripng_nb_config.c +++ b/ripngd/ripng_nb_config.c @@ -163,7 +163,7 @@ int ripngd_instance_default_information_originate_modify( ripng = nb_running_get_entry(args->dnode, NULL, true); default_information = yang_dnode_get_bool(args->dnode, NULL); - str2prefix_ipv6("::/0", &p); + (void)str2prefix_ipv6("::/0", &p); if (default_information) { ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT, &p, 0, NULL, 0); diff --git a/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json b/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json new file mode 100644 index 0000000000..fa89f6b8f2 --- /dev/null +++ b/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json @@ -0,0 +1,191 @@ +{ + "address_types": [ + "ipv4", + "ipv6" + ], + "ipv4base": "10.0.0.0", + "ipv4mask": 24, + "ipv6base": "fd00::", + "ipv6mask": 64, + "link_ip_start": { + "ipv4": "10.0.0.0", + "v4mask": 24, + "ipv6": "fd00::", + "v6mask": 64 + }, + "lo_prefix": { + "ipv4": "1.0.", + "v4mask": 32, + "ipv6": "2001:db8:f::", + "v6mask": 128 + }, + "routers": { + "r1": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r2": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r3": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": {} + } + }, + "r3": { + "dest_link": { + "r1": { + } + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": { + } + } + }, + "r3": { + "dest_link": { + "r1": { + } + } + } + } + } + } + } + } + }, + "r2": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r1": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": { + "route_maps": [{ + "name": "rmap_global", + "direction": "in" + }] + } + } + } + } + } + } + } + }, + "route_maps": { + "rmap_global": [{ + "action": "permit", + "set": { + "ipv6": { + "nexthop": "prefer-global" + } + } + }] + } + }, + "r3": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r1": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "300", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r3": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r3": { + "route_maps": [{ + "name": "rmap_global", + "direction": "in" + }] + } + } + } + } + } + } + } + }, + "route_maps": { + "rmap_global": [{ + "action": "permit", + "set": { + "ipv6": { + "nexthop": "prefer-global" + } + } + }] + } + } + } +} diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py new file mode 100644 index 0000000000..c0842148f1 --- /dev/null +++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py @@ -0,0 +1,422 @@ +#!/usr/bin/python + +# +# Copyright (c) 2020 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test bgp community functionality: +1. Verify that BGP well known communities work fine for + eBGP and iBGP peers. + Well known communities tested: no-export, local-AS, internet + +""" + +import os +import sys +import time +import json +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from mininet.topo import Topo +from lib.topogen import Topogen, get_topogen + +# Import topoJson from lib, to create topology and initial configuration +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + verify_rib, + create_static_routes, + check_address_types, + step, + create_route_maps, + create_prefix_lists, + create_route_maps, + required_linux_kernel_version, +) + +from lib.topolog import logger +from lib.bgp import ( + verify_bgp_convergence, + create_router_bgp, + clear_bgp_and_verify, + verify_bgp_rib, + verify_bgp_community, +) +from lib.topojson import build_topo_from_json, build_config_from_json +from copy import deepcopy + +# Reading the data from JSON File for topology creation +jsonFile = "{}/bgp_communities_topo2.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) + +# Global variables +BGP_CONVERGENCE = False +ADDR_TYPES = check_address_types() +NETWORK = { + "ipv4": ["192.0.2.1/32", "192.0.2.2/32"], + "ipv6": ["2001:DB8::1:1/128", "2001:DB8::1:2/128"], +} + + +class BGPCOMMUNITIES(Topo): + """ + Test BGPCOMMUNITIES - topology 1 + + * `Topo`: Topology object + """ + + def build(self, *_args, **_opts): + """Build function""" + tgen = get_topogen(self) + + # Building topology from json file + build_topo_from_json(tgen, topo) + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("4.14") + if result is not True: + pytest.skip("Kernel requirements are not met") + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + tgen = Topogen(BGPCOMMUNITIES, mod.__name__) + # ... and here it calls Mininet initialization functions. + + # Starting topology, create tmp files which are loaded to routers + # to start deamons and then start routers + start_topology(tgen) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + # Checking BGP convergence + global BGP_CONVERGENCE + global ADDR_TYPES + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Api call verify whether BGP is converged + BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) + assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format( + BGP_CONVERGENCE + ) + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment + + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +##################################################### +# +# Tests starting +# +##################################################### + + +def test_bgp_no_export_local_as_and_internet_communities_p0(request): + """ + Verify that BGP well known communities work fine for + eBGP and iBGP peers. + Well known communities tested: no-export, local-AS, internet + """ + + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Initial config: Configure BGP neighborship between R1 and R3.") + reset_config_on_routers(tgen) + + step("Configure static routes on R1 with next-hop as null0") + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r1": { + "static_routes": [{"network": NETWORK[addr_type], "next_hop": "null0"}] + } + } + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + for comm_type in ["no-export", "local-AS", "internet"]: + + step("Create a route-map on R1 to set community as {}".format(comm_type)) + + seq_id = 10 + input_rmap = { + "r1": { + "route_maps": { + "rmap_wkc": [ + { + "action": "permit", + "seq_id": seq_id, + "set": {"community": {"num": "{}".format(comm_type)}}, + } + ] + } + } + } + result = create_route_maps(tgen, input_rmap) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step("Apply route-map while redistributing static routes into BGP") + input_dict_2 = { + "r1": { + "bgp": { + "address_family": { + "ipv4": { + "unicast": { + "redistribute": [ + { + "redist_type": "static", + "attribute": {"route-map": "rmap_wkc"}, + } + ] + } + }, + "ipv6": { + "unicast": { + "redistribute": [ + { + "redist_type": "static", + "attribute": {"route-map": "rmap_wkc"}, + } + ] + } + }, + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + + step("Verify that BGP prefixes on R1 have community: {}".format(comm_type)) + input_dict_4 = {"community": "{}".format(comm_type)} + for addr_type in ADDR_TYPES: + result = verify_bgp_community( + tgen, addr_type, "r1", NETWORK[addr_type], input_dict_4 + ) + assert result is True, "Test case {} : Should fail \n Error: {}".format( + tc_name, result + ) + + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r1": { + "static_routes": [ + { + "network": NETWORK[addr_type], + "next_hop": topo["routers"]["r2"]["links"]["r1"][ + addr_type + ].split("/")[0], + } + ] + } + } + result = verify_bgp_rib( + tgen, + addr_type, + "r2", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + if comm_type == "internet": + step( + "Verify that these prefixes, originated on R1, are" + "received on both R2 and R3" + ) + + result = verify_rib( + tgen, + addr_type, + "r3", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[ + 0 + ], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + else: + step( + "Verify that these prefixes, originated on R1, are not" + "received on R3 but received on R2" + ) + + result = verify_rib( + tgen, + addr_type, + "r3", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[ + 0 + ], + expected=False, + ) + assert result is not True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + step("Remove route-map from redistribute static on R1") + input_dict_2 = { + "r1": { + "bgp": { + "address_family": { + "ipv4": { + "unicast": { + "redistribute": [ + {"redist_type": "static", "delete": True} + ] + } + }, + "ipv6": { + "unicast": { + "redistribute": [ + {"redist_type": "static", "delete": True} + ] + } + }, + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result) + + step("Configure redistribute static") + input_dict_2 = { + "r1": { + "bgp": { + "address_family": { + "ipv4": { + "unicast": {"redistribute": [{"redist_type": "static"}]} + }, + "ipv6": { + "unicast": {"redistribute": [{"redist_type": "static"}]} + }, + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that these prefixes, originated on R1, are now" + "received on both routers R2 and R3" + ) + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r1": { + "static_routes": [ + { + "network": NETWORK[addr_type], + "next_hop": topo["routers"]["r2"]["links"]["r1"][ + addr_type + ].split("/")[0], + } + ] + } + } + result = verify_bgp_rib( + tgen, + addr_type, + "r2", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + result = verify_bgp_rib( + tgen, + addr_type, + "r3", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index 2e9c4901bc..6e8e749092 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -1,6 +1,6 @@ # Skip pytests example directory [pytest] -norecursedirs = .git example-test example-topojson-test lib docker evpn_type5_test_topo1 +norecursedirs = .git example-test example-topojson-test lib docker [topogen] # Default configuration values diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index d3f9b0c730..7728717e99 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -700,7 +700,6 @@ static int vrrp_master_down_timer_expire(struct thread *thread); */ static int vrrp_bind_to_primary_connected(struct vrrp_router *r) { - char ipstr[INET6_ADDRSTRLEN]; struct interface *ifp; /* @@ -754,20 +753,15 @@ static int vrrp_bind_to_primary_connected(struct vrrp_router *r) if (bind(r->sock_tx, (const struct sockaddr *)&su, sizeof(su)) < 0) { zlog_err( VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM - "Failed to bind Tx socket to primary IP address %s: %s", - r->vr->vrid, family2str(r->family), - inet_ntop(r->family, - (const void *)&c->address->u.prefix, ipstr, - sizeof(ipstr)), + "Failed to bind Tx socket to primary IP address %pFX: %s", + r->vr->vrid, family2str(r->family), c->address, safe_strerror(errno)); ret = -1; } else { DEBUGD(&vrrp_dbg_sock, VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM - "Bound Tx socket to primary IP address %s", - r->vr->vrid, family2str(r->family), - inet_ntop(r->family, (const void *)&c->address->u.prefix, - ipstr, sizeof(ipstr))); + "Bound Tx socket to primary IP address %pFX", + r->vr->vrid, family2str(r->family), c->address); } return ret; @@ -1717,7 +1711,6 @@ static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r) struct listnode *ln; struct connected *c = NULL; bool is_v6_ll; - char ipbuf[INET6_ADDRSTRLEN]; if (!r->mvl_ifp) return; @@ -1730,12 +1723,10 @@ static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r) is_v6_ll = (c->address->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6)); if (c->address->family == r->family && !is_v6_ll) { - inet_ntop(r->family, &c->address->u.prefix, ipbuf, - sizeof(ipbuf)); DEBUGD(&vrrp_dbg_auto, VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM - "Adding %s", - r->vr->vrid, family2str(r->family), ipbuf); + "Adding %pFX", + r->vr->vrid, family2str(r->family), c->address); if (r->family == AF_INET) vrrp_add_ipv4(r->vr, c->address->u.prefix4); else if (r->vr->version == 3) diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c index a578921df6..37a1e4a624 100644 --- a/vrrpd/vrrp_zebra.c +++ b/vrrpd/vrrp_zebra.c @@ -56,8 +56,8 @@ static void vrrp_zebra_debug_if_dump_address(struct interface *ifp, for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { struct prefix *p = ifc->address; - DEBUGD(&vrrp_dbg_zebra, "%s: interface %s address %s %s", func, - ifp->name, inet_ntoa(p->u.prefix4), + DEBUGD(&vrrp_dbg_zebra, "%s: interface %s address %pFX %s", + func, ifp->name, p, CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); } diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index d1003ad5fa..af243f7ca5 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -585,8 +585,7 @@ static void restart_done(struct daemon *dmn) dmn->name, state_str[dmn->state]); return; } - if (dmn->t_wakeup) - THREAD_OFF(dmn->t_wakeup); + THREAD_OFF(dmn->t_wakeup); if (try_connect(dmn) < 0) SET_WAKEUP_DOWN(dmn); } diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 11b252fc18..42a5bfd9db 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -411,47 +411,91 @@ void if_get_flags(struct interface *ifp) { int ret; struct ifreq ifreq; -#ifdef HAVE_BSD_LINK_DETECT - struct ifmediareq ifmr; -#endif /* HAVE_BSD_LINK_DETECT */ ifreq_set_name(&ifreq, ifp); ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id); if (ret < 0) { flog_err_sys(EC_LIB_SYSTEM_CALL, - "vrf_if_ioctl(SIOCGIFFLAGS) failed: %s", - safe_strerror(errno)); + "vrf_if_ioctl(SIOCGIFFLAGS %s) failed: %s", + ifp->name, safe_strerror(errno)); return; } -#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ - /* Per-default, IFF_RUNNING is held high, unless link-detect says - * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag, - * following practice on Linux and Solaris kernels + if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) + goto out; + + /* Per-default, IFF_RUNNING is held high, unless link-detect + * says otherwise - we abuse IFF_RUNNING inside zebra as a + * link-state flag, following practice on Linux and Solaris + * kernels + */ + +#ifdef SIOCGIFDATA + /* + * BSD gets link state from ifi_link_link in struct if_data. + * All BSD's have this in getifaddrs(3) ifa_data for AF_LINK + * addresses. We can also access it via SIOCGIFDATA. + */ + +#ifdef __NetBSD__ + struct ifdatareq ifdr = {.ifdr_data.ifi_link_state = 0}; + struct if_data *ifdata = &ifdr.ifdr_data; + + strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name)); + ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifdr, ifp->vrf_id); +#else + struct if_data ifd = {.ifi_link_state = 0}; + struct if_data *ifdata = &ifd; + + ifreq.ifr_data = (caddr_t)ifdata; + ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreq, ifp->vrf_id); +#endif + + if (ret == -1) + /* Very unlikely. Did the interface disappear? */ + flog_err_sys(EC_LIB_SYSTEM_CALL, + "if_ioctl(SIOCGIFDATA %s) failed: %s", ifp->name, + safe_strerror(errno)); + else { + if (ifdata->ifi_link_state >= LINK_STATE_UP) + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN) + /* BSD traditionally treats UNKNOWN as UP */ + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + } + +#elif defined(HAVE_BSD_LINK_DETECT) + /* + * This is only needed for FreeBSD older than FreeBSD-13. + * Valid and active media generally means the link state is + * up, but this is not always the case. + * For example, some BSD's with a net80211 interface in MONITOR + * mode will treat the media as valid and active but the + * link state is down - because we cannot send anything. + * Also, virtual interfaces such as PPP, VLAN, etc generally + * don't support media at all, so the ioctl will just fail. */ - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + struct ifmediareq ifmr = {.ifm_status = 0}; - if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) { - (void)memset(&ifmr, 0, sizeof(ifmr)); - strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); + strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); - /* Seems not all interfaces implement this ioctl */ - if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1 && - errno != EINVAL) + if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) { + if (errno != EINVAL) flog_err_sys(EC_LIB_SYSTEM_CALL, - "if_ioctl(SIOCGIFMEDIA) failed: %s", - safe_strerror(errno)); - else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ - { - if (ifmr.ifm_status & IFM_ACTIVE) - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - else - UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - } + "if_ioctl(SIOCGIFMEDIA %s) failed: %s", + ifp->name, safe_strerror(errno)); + } else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */ + if (ifmr.ifm_status & IFM_ACTIVE) /* media is active */ + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); } #endif /* HAVE_BSD_LINK_DETECT */ +out: if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff)); } diff --git a/zebra/main.c b/zebra/main.c index 2afef46bb2..6b6409f845 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -87,7 +87,6 @@ uint32_t nl_rcvbufsize = 4194304; const struct option longopts[] = { {"batch", no_argument, NULL, 'b'}, {"allow_delete", no_argument, NULL, 'a'}, - {"keep_kernel", no_argument, NULL, 'k'}, {"socket", required_argument, NULL, 'z'}, {"ecmp", required_argument, NULL, 'e'}, {"retain", no_argument, NULL, 'r'}, diff --git a/zebra/zebra_mlag_private.c b/zebra/zebra_mlag_private.c index 343e7801db..8a66d6de72 100644 --- a/zebra/zebra_mlag_private.c +++ b/zebra/zebra_mlag_private.c @@ -74,9 +74,10 @@ static void zebra_mlag_sched_read(void) static int zebra_mlag_read(struct thread *thread) { + static uint32_t mlag_rd_buf_offset; uint32_t *msglen; uint32_t h_msglen; - uint32_t tot_len, curr_len = 0; + uint32_t tot_len, curr_len = mlag_rd_buf_offset; /* * Received message in sock_stream looks like below @@ -99,6 +100,7 @@ static int zebra_mlag_read(struct thread *thread) zebra_mlag_handle_process_state(MLAG_DOWN); return -1; } + mlag_rd_buf_offset += data_len; if (data_len != (ssize_t)(ZEBRA_MLAG_LEN_SIZE - curr_len)) { /* Try again later */ zebra_mlag_sched_read(); @@ -136,6 +138,7 @@ static int zebra_mlag_read(struct thread *thread) zebra_mlag_handle_process_state(MLAG_DOWN); return -1; } + mlag_rd_buf_offset += data_len; if (data_len != (ssize_t)(tot_len - curr_len)) { /* Try again later */ zebra_mlag_sched_read(); @@ -157,6 +160,7 @@ static int zebra_mlag_read(struct thread *thread) /* Register read thread. */ zebra_mlag_reset_read_buffer(); + mlag_rd_buf_offset = 0; zebra_mlag_sched_read(); return 0; } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 03b8c8de1f..e0ad4f1cbe 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -52,10 +52,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object") -DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config") DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname") int mpls_enabled; @@ -101,7 +98,8 @@ static void lsp_check_free(struct hash *lsp_table, zebra_lsp_t **plsp); /* Free lsp; sets caller's pointer to NULL */ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp); -static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size); +static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size); +static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size); static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, const union g_addr *gate, ifindex_t ifindex); static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list, @@ -124,19 +122,6 @@ static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty, const char *indent); static void lsp_print(struct vty *vty, zebra_lsp_t *lsp); -static void *slsp_alloc(void *p); -static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex); -static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex); -static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex, - mpls_label_t out_label); -static int snhlfe_del(zebra_snhlfe_t *snhlfe); -static int snhlfe_del_all(zebra_slsp_t *slsp); -static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size); static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt); static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi, enum lsp_types_t lsp_type); @@ -145,9 +130,6 @@ static int lsp_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type, static int lsp_backup_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type, const struct zapi_nexthop *znh); -/* List implementations - declare internal linkage */ -DECLARE_DLIST(snhlfe_list, struct zebra_snhlfe_t_, list); - /* Static functions */ /* @@ -1173,9 +1155,9 @@ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp) /* * Create printable string for NHLFE entry. */ -static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size) +static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size) { - struct nexthop *nexthop; + const struct nexthop *nexthop; buf[0] = '\0'; nexthop = nhlfe->nexthop; @@ -1414,7 +1396,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, continue; if (IS_ZEBRA_DEBUG_MPLS) { - nhlfe2str(nhlfe, buf, BUFSIZ); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Del LSP in-label %u type %d nexthop %s flags 0x%x", lsp->ile.in_label, type, buf, nhlfe->flags); @@ -1435,7 +1417,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, continue; if (IS_ZEBRA_DEBUG_MPLS) { - nhlfe2str(nhlfe, buf, BUFSIZ); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Del backup LSP in-label %u type %d nexthop %s flags 0x%x", lsp->ile.in_label, type, buf, nhlfe->flags); @@ -1711,188 +1693,6 @@ static int lsp_cmp(const zebra_lsp_t *lsp1, const zebra_lsp_t *lsp2) } /* - * Callback to allocate static LSP. - */ -static void *slsp_alloc(void *p) -{ - const zebra_ile_t *ile = p; - zebra_slsp_t *slsp; - - slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t)); - slsp->ile = *ile; - snhlfe_list_init(&slsp->snhlfe_list); - - return ((void *)slsp); -} - -/* - * Compare two static LSPs based on their label values. - */ -static int slsp_cmp(const zebra_slsp_t *slsp1, const zebra_slsp_t *slsp2) -{ - if (slsp1->ile.in_label < slsp2->ile.in_label) - return -1; - - if (slsp1->ile.in_label > slsp2->ile.in_label) - return 1; - - return 0; -} - -/* - * Check if static NHLFE matches with search info passed. - */ -static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex) -{ - int cmp = 1; - - if (snhlfe->gtype != gtype) - return 1; - - switch (snhlfe->gtype) { - case NEXTHOP_TYPE_IPV4: - cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4), - sizeof(struct in_addr)); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6), - sizeof(struct in6_addr)); - if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX) - cmp = !(snhlfe->ifindex == ifindex); - break; - default: - break; - } - - return cmp; -} - -/* - * Locate static NHLFE that matches with passed info. - */ -static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex) -{ - zebra_snhlfe_t *snhlfe; - - if (!slsp) - return NULL; - - frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) { - if (!snhlfe_match(snhlfe, gtype, gate, ifindex)) - break; - } - - return snhlfe; -} - - -/* - * Add static NHLFE. Base LSP config entry must have been created - * and duplicate check done. - */ -static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex, - mpls_label_t out_label) -{ - zebra_snhlfe_t *snhlfe; - - if (!slsp) - return NULL; - - snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t)); - snhlfe->slsp = slsp; - snhlfe->out_label = out_label; - snhlfe->gtype = gtype; - switch (gtype) { - case NEXTHOP_TYPE_IPV4: - snhlfe->gate.ipv4 = gate->ipv4; - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - snhlfe->gate.ipv6 = gate->ipv6; - if (ifindex) - snhlfe->ifindex = ifindex; - break; - default: - XFREE(MTYPE_SNHLFE, snhlfe); - return NULL; - } - - snhlfe_list_add_head(&slsp->snhlfe_list, snhlfe); - - return snhlfe; -} - -/* - * Delete static NHLFE. Entry must be present on list. - */ -static int snhlfe_del(zebra_snhlfe_t *snhlfe) -{ - zebra_slsp_t *slsp; - - if (!snhlfe) - return -1; - - slsp = snhlfe->slsp; - if (!slsp) - return -1; - - snhlfe_list_del(&slsp->snhlfe_list, snhlfe); - - XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname); - XFREE(MTYPE_SNHLFE, snhlfe); - - return 0; -} - -/* - * Delete all static NHLFE entries for this LSP (in label). - */ -static int snhlfe_del_all(zebra_slsp_t *slsp) -{ - zebra_snhlfe_t *snhlfe; - - if (!slsp) - return -1; - - frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) { - snhlfe_del(snhlfe); - } - - return 0; -} - -/* - * Create printable string for NHLFE configuration. - */ -static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size) -{ - buf[0] = '\0'; - switch (snhlfe->gtype) { - case NEXTHOP_TYPE_IPV4: - inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size); - if (snhlfe->ifindex) - strlcat(buf, - ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT), - size); - break; - default: - break; - } - - return buf; -} - -/* * Initialize work queue for processing changed LSPs. */ static int mpls_processq_init(void) @@ -3633,8 +3433,9 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, { struct hash *slsp_table; zebra_ile_t tmp_ile; - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; + const struct nexthop *nh; /* Lookup table. */ slsp_table = zvrf->slsp_table; @@ -3643,26 +3444,37 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, /* If entry is not present, exit. */ tmp_ile.in_label = in_label; - slsp = hash_lookup(slsp_table, &tmp_ile); - if (!slsp) + lsp = hash_lookup(slsp_table, &tmp_ile); + if (!lsp) return 1; - snhlfe = snhlfe_find(slsp, gtype, gate, ifindex); - if (snhlfe) { - if (snhlfe->out_label == out_label) + nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, + gtype, gate, ifindex); + if (nhlfe) { + nh = nhlfe->nexthop; + + if (nh == NULL || nh->nh_label == NULL) + return 0; + + if (nh->nh_label->label[0] == out_label) return 1; /* If not only NHLFE, cannot allow label change. */ - if (snhlfe != snhlfe_list_first(&slsp->snhlfe_list) || - snhlfe_list_next(&slsp->snhlfe_list, snhlfe) != NULL) + if (nhlfe != nhlfe_list_first(&lsp->nhlfe_list) || + nhlfe_list_next(&lsp->nhlfe_list, nhlfe) != NULL) return 0; } else { /* If other NHLFEs exist, label operation must match. */ - snhlfe = snhlfe_list_first(&slsp->snhlfe_list); - if (snhlfe != NULL) { + nhlfe = nhlfe_list_first(&lsp->nhlfe_list); + if (nhlfe != NULL) { int cur_op, new_op; - cur_op = (snhlfe->out_label == + nh = nhlfe->nexthop; + + if (nh == NULL || nh->nh_label == NULL) + return 0; + + cur_op = (nh->nh_label->label[0] == MPLS_LABEL_IMPLICIT_NULL); new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL); if (cur_op != new_op) @@ -3689,8 +3501,8 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, { struct hash *slsp_table; zebra_ile_t tmp_ile; - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; char buf[BUFSIZ]; /* Lookup table. */ @@ -3700,31 +3512,47 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, /* Find or create LSP. */ tmp_ile.in_label = in_label; - slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc); - if (!slsp) + lsp = hash_get(slsp_table, &tmp_ile, lsp_alloc); + if (!lsp) return -1; - snhlfe = snhlfe_find(slsp, gtype, gate, ifindex); - if (snhlfe) { - if (snhlfe->out_label == out_label) + nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, gtype, gate, + ifindex); + if (nhlfe) { + struct nexthop *nh = nhlfe->nexthop; + + assert(nh); + assert(nh->nh_label); + + /* Compare existing nexthop */ + if (nh->nh_label->num_labels == 1 && + nh->nh_label->label[0] == out_label) /* No change */ return 0; if (IS_ZEBRA_DEBUG_MPLS) { - snhlfe2str(snhlfe, buf, sizeof(buf)); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Upd static LSP in-label %u nexthop %s out-label %u (old %u)", - in_label, buf, out_label, snhlfe->out_label); + in_label, buf, out_label, + nh->nh_label->label[0]); + } + if (nh->nh_label->num_labels == 1) + nh->nh_label->label[0] = out_label; + else { + nexthop_del_labels(nh); + nexthop_add_labels(nh, ZEBRA_LSP_STATIC, 1, &out_label); } - snhlfe->out_label = out_label; + } else { /* Add static LSP entry to this nexthop */ - snhlfe = snhlfe_add(slsp, gtype, gate, ifindex, out_label); - if (!snhlfe) + nhlfe = nhlfe_add(lsp, ZEBRA_LSP_STATIC, gtype, gate, + ifindex, 1, &out_label, false /*backup*/); + if (!nhlfe) return -1; if (IS_ZEBRA_DEBUG_MPLS) { - snhlfe2str(snhlfe, buf, sizeof(buf)); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Add static LSP in-label %u nexthop %s out-label %u", in_label, buf, out_label); @@ -3752,8 +3580,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, { struct hash *slsp_table; zebra_ile_t tmp_ile; - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; /* Lookup table. */ slsp_table = zvrf->slsp_table; @@ -3762,8 +3590,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, /* If entry is not present, exit. */ tmp_ile.in_label = in_label; - slsp = hash_lookup(slsp_table, &tmp_ile); - if (!slsp) + lsp = hash_lookup(slsp_table, &tmp_ile); + if (!lsp) return 0; /* Is it delete of entire LSP or a specific NHLFE? */ @@ -3775,16 +3603,19 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, mpls_static_lsp_uninstall_all(zvrf, in_label); /* Delete all static NHLFEs */ - snhlfe_del_all(slsp); + frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) { + nhlfe_del(nhlfe); + } } else { /* Find specific NHLFE, exit if not found. */ - snhlfe = snhlfe_find(slsp, gtype, gate, ifindex); - if (!snhlfe) + nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, + gtype, gate, ifindex); + if (!nhlfe) return 0; if (IS_ZEBRA_DEBUG_MPLS) { char buf[BUFSIZ]; - snhlfe2str(snhlfe, buf, BUFSIZ); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug("Del static LSP in-label %u nexthop %s", in_label, buf); } @@ -3794,14 +3625,15 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, gate, ifindex, false); /* Delete static LSP NHLFE */ - snhlfe_del(snhlfe); + nhlfe_del(nhlfe); } /* Remove entire static LSP entry if no NHLFE - valid in either case - * above. */ - if (snhlfe_list_first(&slsp->snhlfe_list) == NULL) { - slsp = hash_release(slsp_table, &tmp_ile); - XFREE(MTYPE_SLSP, slsp); + * above. + */ + if (nhlfe_list_first(&lsp->nhlfe_list) == NULL) { + lsp = hash_release(slsp_table, &tmp_ile); + XFREE(MTYPE_LSP, lsp); } return 0; @@ -3949,23 +3781,58 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, } /* + * Create printable string for static LSP configuration. + */ +static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size) +{ + const struct nexthop *nh; + + nh = nhlfe->nexthop; + + buf[0] = '\0'; + switch (nh->type) { + case NEXTHOP_TYPE_IPV4: + inet_ntop(AF_INET, &nh->gate.ipv4, buf, size); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + inet_ntop(AF_INET6, &nh->gate.ipv6, buf, size); + if (nh->ifindex) + strlcat(buf, + ifindex2ifname(nh->ifindex, VRF_DEFAULT), + size); + break; + default: + break; + } + + return buf; +} + +/* * Display MPLS LSP configuration of all static LSPs (VTY command handler). */ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) { - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; + struct nexthop *nh; struct listnode *node; struct list *slsp_list = - hash_get_sorted_list(zvrf->slsp_table, slsp_cmp); + hash_get_sorted_list(zvrf->slsp_table, lsp_cmp); - for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) { - frr_each(snhlfe_list, &slsp->snhlfe_list, snhlfe) { + for (ALL_LIST_ELEMENTS_RO(slsp_list, node, lsp)) { + frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) { char buf[BUFSIZ]; char lstr[30]; - snhlfe2str(snhlfe, buf, sizeof(buf)); - switch (snhlfe->out_label) { + nh = nhlfe->nexthop; + if (nh == NULL || nh->nh_label == NULL) + continue; + + nhlfe_config_str(nhlfe, buf, sizeof(buf)); + + switch (nh->nh_label->label[0]) { case MPLS_LABEL_IPV4_EXPLICIT_NULL: case MPLS_LABEL_IPV6_EXPLICIT_NULL: strlcpy(lstr, "explicit-null", sizeof(lstr)); @@ -3975,11 +3842,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) break; default: snprintf(lstr, sizeof(lstr), "%u", - snhlfe->out_label); + nh->nh_label->label[0]); break; } - vty_out(vty, "mpls lsp %u %s %s\n", slsp->ile.in_label, + vty_out(vty, "mpls lsp %u %s %s\n", lsp->ile.in_label, buf, lstr); } } diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index c0e58c44e3..5167233040 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -50,37 +50,14 @@ extern "C" { /* Typedefs */ typedef struct zebra_ile_t_ zebra_ile_t; -typedef struct zebra_snhlfe_t_ zebra_snhlfe_t; -typedef struct zebra_slsp_t_ zebra_slsp_t; typedef struct zebra_nhlfe_t_ zebra_nhlfe_t; typedef struct zebra_lsp_t_ zebra_lsp_t; typedef struct zebra_fec_t_ zebra_fec_t; /* Declare LSP nexthop list types */ -PREDECL_DLIST(snhlfe_list); PREDECL_DLIST(nhlfe_list); /* - * (Outgoing) nexthop label forwarding entry configuration - */ -struct zebra_snhlfe_t_ { - /* Nexthop information */ - enum nexthop_types_t gtype; - union g_addr gate; - char *ifname; - ifindex_t ifindex; - - /* Out label. */ - mpls_label_t out_label; - - /* Backpointer to base entry. */ - zebra_slsp_t *slsp; - - /* Linkage for LSPs' lists */ - struct snhlfe_list_item list; -}; - -/* * (Outgoing) nexthop label forwarding entry */ struct zebra_nhlfe_t_ { @@ -116,17 +93,6 @@ struct zebra_ile_t_ { }; /* - * Label swap entry static configuration. - */ -struct zebra_slsp_t_ { - /* Incoming label */ - zebra_ile_t ile; - - /* List of outgoing nexthop static configuration */ - struct snhlfe_list_head snhlfe_list; -}; - -/* * Label swap entry (ile -> list of nhlfes) */ struct zebra_lsp_t_ { diff --git a/zebra/zebra_opaque.c b/zebra/zebra_opaque.c index 41e278f71b..1d59e0ab34 100644 --- a/zebra/zebra_opaque.c +++ b/zebra/zebra_opaque.c @@ -258,7 +258,7 @@ uint32_t zebra_opaque_enqueue_batch(struct stream_fifo *batch) /* Schedule module pthread to process the batch */ if (counter > 0) { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: received %u messages", __func__, counter); thread_add_event(zo_info.master, process_messages, NULL, 0, @@ -315,7 +315,7 @@ static int process_messages(struct thread *event) goto done; } - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: processing %u messages", __func__, i); /* @@ -381,7 +381,7 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) /* Look up registered ZAPI client(s) */ reg = opq_reg_lookup(info.type); if (reg == NULL) { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: no registrations for opaque type %u, flags %#x", __func__, info.type, info.flags); goto drop_it; @@ -401,7 +401,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) client->session_id != info.session_id) continue; - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && + IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: found matching unicast client %s", __func__, opq_client2str(buf, @@ -423,7 +424,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) client->instance, client->session_id); if (zclient) { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_SEND && + IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: sending %s to client %s", __func__, (dup ? "dup" : "msg"), @@ -444,7 +446,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) zserv_release_client(zclient); } else { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && + IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: type %u: no zclient for %s", __func__, info.type, opq_client2str(buf, @@ -615,10 +618,6 @@ static int handle_opq_unregistration(const struct zmsghdr *hdr, /* Is registration empty now? */ if (reg->clients == NULL) { - if (IS_ZEBRA_DEBUG_RECV) - zlog_debug("%s: free empty reg %u", __func__, - reg->type); - opq_regh_del(&opq_reg_hash, reg); opq_reg_free(®); } |
