diff options
190 files changed, 2946 insertions, 3124 deletions
diff --git a/.clang-format b/.clang-format index 2710d844e9..21fe9d7c5e 100644 --- a/.clang-format +++ b/.clang-format @@ -41,6 +41,8 @@ ForEachMacros: - RB_FOREACH_REVERSE - RB_FOREACH_REVERSE_SAFE - SPLAY_FOREACH + - FOR_ALL_INTERFACES + - FOR_ALL_INTERFACES_ADDRESSES # zebra - RE_DEST_FOREACH_ROUTE - RE_DEST_FOREACH_ROUTE_SAFE diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 4419160cd7..d4958ddf24 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -138,7 +138,7 @@ babel_interface_delete (int cmd, struct zclient *client, zebra_size_t length, vr /* To support pseudo interface do not free interface structure. */ /* if_delete(ifp); */ - ifp->ifindex = IFINDEX_INTERNAL; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } @@ -809,10 +809,10 @@ interface_reset(struct interface *ifp) void babel_interface_close_all(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp = NULL; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { if(!if_up(ifp)) continue; send_wildcard_retraction(ifp); @@ -823,7 +823,7 @@ babel_interface_close_all(void) usleep(roughly(1000)); gettime(&babel_now); } - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { if(!if_up(ifp)) continue; /* Make sure they got it. */ @@ -896,12 +896,12 @@ DEFUN (show_babel_interface, "Interface information\n" "Interface\n") { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; if (argc == 3) { - for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) show_babel_interface_sub (vty, ifp); return CMD_SUCCESS; } @@ -1316,11 +1316,11 @@ babeld-specific statement lines where appropriate. */ static int interface_config_write (struct vty *vty) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; int write = 0; - for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { vty_frame (vty, "interface %s\n",ifp->name); if (ifp->desc) vty_out (vty, " description %s\n",ifp->desc); diff --git a/babeld/babel_interface.h b/babeld/babel_interface.h index 64509afa17..17d9bfb936 100644 --- a/babeld/babel_interface.h +++ b/babeld/babel_interface.h @@ -50,7 +50,7 @@ struct babel_interface { char have_buffered_id; char have_buffered_nh; char have_buffered_prefix; - unsigned char buffered_id[16]; + unsigned char buffered_id[8]; unsigned char buffered_nh[4]; unsigned char buffered_prefix[16]; unsigned char *sendbuf; @@ -103,16 +103,6 @@ if_up(struct interface *ifp) (babel_get_if_nfo(ifp)->flags & BABEL_IF_IS_UP)); } -/* types: - struct interface _ifp, struct listnode node */ -#define FOR_ALL_INTERFACES(_ifp, _node) \ - for(ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), _node, _ifp)) - -/* types: - struct interface *ifp, struct connected *_connected, struct listnode *node */ -#define FOR_ALL_INTERFACES_ADDRESSES(ifp, _connected, _node) \ - for(ALL_LIST_ELEMENTS_RO(ifp->connected, _node, _connected)) - struct buffered_update { unsigned char id[8]; unsigned char prefix[16]; @@ -120,7 +110,6 @@ struct buffered_update { unsigned char pad[3]; }; - /* init function */ void babel_if_init(void); diff --git a/babeld/babeld.c b/babeld/babeld.c index 207c37d9b1..00367612c6 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -164,9 +164,9 @@ static int babel_read_protocol (struct thread *thread) { int rc; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp = NULL; struct sockaddr_in6 sin6; - struct listnode *linklist_node = NULL; assert(babel_routing_process != NULL); assert(protocol_socket >= 0); @@ -179,7 +179,7 @@ babel_read_protocol (struct thread *thread) zlog_err("recv: %s", safe_strerror(errno)); } } else { - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { if(!if_up(ifp)) continue; if(ifp->ifindex == (ifindex_t)sin6.sin6_scope_id) { @@ -214,8 +214,8 @@ babel_init_routing_process(struct thread *thread) static void babel_get_myid(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp = NULL; - struct listnode *linklist_node = NULL; int rc; int i; @@ -224,7 +224,7 @@ babel_get_myid(void) return; } - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { /* ifp->ifindex is not necessarily valid at this point */ int ifindex = if_nametoindex(ifp->name); if(ifindex > 0) { @@ -268,10 +268,10 @@ babel_get_myid(void) static void babel_initial_noise(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp = NULL; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { if(!if_up(ifp)) continue; /* Apply jitter before we send the first message. */ @@ -281,7 +281,7 @@ babel_initial_noise(void) send_wildcard_retraction(ifp); } - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { if(!if_up(ifp)) continue; usleep(roughly(10000)); @@ -319,8 +319,8 @@ static int babel_main_loop(struct thread *thread) { struct timeval tv; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp = NULL; - struct listnode *linklist_node = NULL; while(1) { gettime(&babel_now); @@ -361,7 +361,7 @@ babel_main_loop(struct thread *thread) source_expiry_time = babel_now.tv_sec + roughly(300); } - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { babel_interface_nfo *babel_ifp = NULL; if(!if_up(ifp)) continue; @@ -385,7 +385,7 @@ babel_main_loop(struct thread *thread) flush_unicast(1); } - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { babel_interface_nfo *babel_ifp = NULL; if(!if_up(ifp)) continue; @@ -449,8 +449,8 @@ babel_fill_with_next_timeout(struct timeval *tv) #define printIfMin(a,b,c,d) \ if (UNLIKELY(debug & BABEL_DEBUG_TIMEOUT)) {printIfMin(a,b,c,d);} + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp = NULL; - struct listnode *linklist_node = NULL; *tv = check_neighbours_timeout; printIfMin(tv, 0, "check_neighbours_timeout", NULL); @@ -460,7 +460,7 @@ babel_fill_with_next_timeout(struct timeval *tv) printIfMin(tv, 1, "source_expiry_time", NULL); timeval_min(tv, &resend_time); printIfMin(tv, 1, "resend_time", NULL); - FOR_ALL_INTERFACES(ifp, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp) { babel_interface_nfo *babel_ifp = NULL; if(!if_up(ifp)) continue; @@ -578,10 +578,10 @@ babel_distribute_update_interface (struct interface *ifp) static void babel_distribute_update_all (struct prefix_list *notused) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) babel_distribute_update_interface (ifp); } diff --git a/babeld/message.c b/babeld/message.c index e31d5de5df..1ff4867908 100644 --- a/babeld/message.c +++ b/babeld/message.c @@ -1080,7 +1080,7 @@ really_send_update(struct interface *ifp, accumulate_bytes(ifp, id, 8); end_message(ifp, MESSAGE_ROUTER_ID, 10); } - memcpy(babel_ifp->buffered_id, id, 16); + memcpy(babel_ifp->buffered_id, id, sizeof(babel_ifp->buffered_id)); babel_ifp->have_buffered_id = 1; } @@ -1154,9 +1154,9 @@ flushupdates(struct interface *ifp) int i; if(ifp == NULL) { - struct interface *ifp_aux; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct interface *ifp_aux; + FOR_ALL_INTERFACES(vrf, ifp_aux) flushupdates(ifp_aux); return; } @@ -1326,10 +1326,10 @@ send_update(struct interface *ifp, int urgent, babel_interface_nfo *babel_ifp = NULL; if(ifp == NULL) { - struct interface *ifp_aux; - struct listnode *linklist_node = NULL; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct interface *ifp_aux; struct babel_route *route; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) + FOR_ALL_INTERFACES(vrf, ifp_aux) send_update(ifp_aux, urgent, prefix, plen); if(prefix) { /* Since flushupdates only deals with non-wildcard interfaces, we @@ -1387,9 +1387,9 @@ send_wildcard_retraction(struct interface *ifp) { babel_interface_nfo *babel_ifp = NULL; if(ifp == NULL) { - struct interface *ifp_aux; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct interface *ifp_aux; + FOR_ALL_INTERFACES(vrf, ifp_aux) send_wildcard_retraction(ifp_aux); return; } @@ -1422,9 +1422,9 @@ send_self_update(struct interface *ifp) { struct xroute_stream *xroutes; if(ifp == NULL) { - struct interface *ifp_aux; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct interface *ifp_aux; + FOR_ALL_INTERFACES(vrf, ifp_aux) { if(!if_up(ifp_aux)) continue; send_self_update(ifp_aux); @@ -1456,9 +1456,9 @@ send_ihu(struct neighbour *neigh, struct interface *ifp) int msglen; if(neigh == NULL && ifp == NULL) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp_aux; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) { + FOR_ALL_INTERFACES(vrf, ifp_aux) { if(if_up(ifp_aux)) continue; send_ihu(NULL, ifp_aux); @@ -1573,9 +1573,9 @@ send_request(struct interface *ifp, int v4, pb, len; if(ifp == NULL) { - struct interface *ifp_aux; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct interface *ifp_aux; + FOR_ALL_INTERFACES(vrf, ifp_aux) { if(if_up(ifp_aux)) continue; send_request(ifp_aux, prefix, plen); @@ -1648,9 +1648,9 @@ send_multihop_request(struct interface *ifp, flushupdates(ifp); if(ifp == NULL) { - struct interface *ifp_aux; - struct listnode *linklist_node = NULL; - FOR_ALL_INTERFACES(ifp_aux, linklist_node) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct interface *ifp_aux; + FOR_ALL_INTERFACES(vrf, ifp_aux) { if(!if_up(ifp_aux)) continue; send_multihop_request(ifp_aux, prefix, plen, seqno, id, hop_count); diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 2b776d2182..6c03ba3059 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -1914,7 +1914,8 @@ static const char *aspath_gettoken(const char *buf, enum as_token *token, /* There is no match then return unknown token. */ *token = as_token_unknown; - return p++; + p++; + return p; } struct aspath *aspath_str2aspath(const char *str) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 97b6273cb4..c178089af7 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1849,7 +1849,6 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ u_char *startp) { bgp_size_t total; - struct bgp_attr_encap_subtlv *stlv_last = NULL; uint16_t tunneltype = 0; total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); @@ -1926,6 +1925,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ /* attach tlv to encap chain */ if (BGP_ATTR_ENCAP == type) { + struct bgp_attr_encap_subtlv *stlv_last; for (stlv_last = attr->encap_subtlvs; stlv_last && stlv_last->next; stlv_last = stlv_last->next) @@ -1937,6 +1937,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ } #if ENABLE_BGP_VNC } else { + struct bgp_attr_encap_subtlv *stlv_last; for (stlv_last = attr->vnc_subtlvs; stlv_last && stlv_last->next; stlv_last = stlv_last->next) @@ -1948,7 +1949,6 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ } #endif } - stlv_last = tlv; } if (BGP_ATTR_ENCAP == type) { diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 6923479cb2..a09d966d7b 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -288,7 +288,7 @@ static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn, /* Delete VNI from hash list for this RT. */ listnode_delete(irt->vnis, vpn); if (!listnode_head(irt->vnis)) { - list_free(irt->vnis); + list_delete_and_null(&irt->vnis); import_rt_free(bgp, irt); } } @@ -2609,10 +2609,8 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) { bgp_table_unlock(vpn->route_table); bgp_evpn_unmap_vni_from_its_rts(bgp, vpn); - list_delete(vpn->import_rtl); - list_delete(vpn->export_rtl); - vpn->import_rtl = NULL; - vpn->export_rtl = NULL; + list_delete_and_null(&vpn->import_rtl); + list_delete_and_null(&vpn->export_rtl); bf_release_index(bgp->rd_idspace, vpn->rd_id); hash_release(bgp->vnihash, vpn); QOBJ_UNREG(vpn); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 7454aec892..07b86c05d6 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2144,7 +2144,7 @@ static void write_vni_config_for_entry(struct hash_backet *backet, DEFUN (bgp_evpn_advertise_default_gw_vni, bgp_evpn_advertise_default_gw_vni_cmd, "advertise-default-gw", - "Advertise defualt g/w mac-ip routes in EVPN for a VNI\n") + "Advertise default g/w mac-ip routes in EVPN for a VNI\n") { struct bgp *bgp = VTY_GET_CONTEXT(bgp); VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn); @@ -2184,7 +2184,7 @@ DEFUN (no_bgp_evpn_advertise_default_vni_gw, DEFUN (bgp_evpn_advertise_default_gw, bgp_evpn_advertise_default_gw_cmd, "advertise-default-gw", - "Advertise All defualt g/w mac-ip routes in EVPN\n") + "Advertise All default g/w mac-ip routes in EVPN\n") { struct bgp *bgp = VTY_GET_CONTEXT(bgp); @@ -3102,11 +3102,11 @@ DEFUN (bgp_evpn_vni_rt, if (!bgp || !vpn) return CMD_WARNING; - if (!strcmp(argv[1]->arg, "import")) + if (!strcmp(argv[1]->text, "import")) rt_type = RT_TYPE_IMPORT; - else if (!strcmp(argv[1]->arg, "export")) + else if (!strcmp(argv[1]->text, "export")) rt_type = RT_TYPE_EXPORT; - else if (!strcmp(argv[1]->arg, "both")) + else if (!strcmp(argv[1]->text, "both")) rt_type = RT_TYPE_BOTH; else { vty_out(vty, "%% Invalid Route Target type\n"); @@ -3164,11 +3164,11 @@ DEFUN (no_bgp_evpn_vni_rt, if (!bgp || !vpn) return CMD_WARNING; - if (!strcmp(argv[2]->arg, "import")) + if (!strcmp(argv[2]->text, "import")) rt_type = RT_TYPE_IMPORT; - else if (!strcmp(argv[2]->arg, "export")) + else if (!strcmp(argv[2]->text, "export")) rt_type = RT_TYPE_EXPORT; - else if (!strcmp(argv[2]->arg, "both")) + else if (!strcmp(argv[2]->text, "both")) rt_type = RT_TYPE_BOTH; else { vty_out(vty, "%% Invalid Route Target type\n"); @@ -3257,9 +3257,9 @@ DEFUN (no_bgp_evpn_vni_rt_without_val, if (!bgp || !vpn) return CMD_WARNING; - if (!strcmp(argv[2]->arg, "import")) { + if (!strcmp(argv[2]->text, "import")) { rt_type = RT_TYPE_IMPORT; - } else if (!strcmp(argv[2]->arg, "export")) { + } else if (!strcmp(argv[2]->text, "export")) { rt_type = RT_TYPE_EXPORT; } else { vty_out(vty, "%% Invalid Route Target type\n"); diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index 6e1a1b6d62..ae9d805b05 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -410,8 +410,8 @@ DEFUN (ip_as_path, char *regstr; /* Retrieve access list name */ - char *alname = - argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL; + argv_find(argv, argc, "WORD", &idx); + char *alname = argv[idx]->arg; /* Check the filter type. */ type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index ad7411990e..06c314de03 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -225,7 +225,6 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, for (; pnt < lim; pnt += psize) { /* Clear prefix structure. */ memset(&p, 0, sizeof(struct prefix)); - llen = 0; if (addpath_encoded) { diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index dfd639c92c..1fac2936eb 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -215,7 +215,7 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) #endif bgp_zebra_destroy(); - list_delete(bm->bgp); + list_delete_and_null(&bm->bgp); memset(bm, 0, sizeof(*bm)); frr_fini(); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 694cb14790..472b9d200a 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -356,19 +356,6 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, { struct bgp *bgp; struct bgp_table *table; - struct bgp_node *rn; - struct bgp_node *rm; - struct bgp_info *ri; - int rd_header; - int header = 1; - unsigned long output_count = 0; - unsigned long total_count = 0; - json_object *json = NULL; - json_object *json_mroute = NULL; - json_object *json_nroute = NULL; - json_object *json_array = NULL; - json_object *json_scode = NULL; - json_object *json_ocode = NULL; bgp = bgp_get_default(); if (bgp == NULL) { @@ -378,279 +365,31 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, vty_out(vty, "{}\n"); return CMD_WARNING; } - - if (use_json) { - json_scode = json_object_new_object(); - json_ocode = json_object_new_object(); - json = json_object_new_object(); - json_mroute = json_object_new_object(); - json_nroute = json_object_new_object(); - - json_object_string_add(json_scode, "suppressed", "s"); - json_object_string_add(json_scode, "damped", "d"); - json_object_string_add(json_scode, "history", "h"); - json_object_string_add(json_scode, "valid", "*"); - json_object_string_add(json_scode, "best", ">"); - json_object_string_add(json_scode, "internal", "i"); - - json_object_string_add(json_ocode, "igp", "i"); - json_object_string_add(json_ocode, "egp", "e"); - json_object_string_add(json_ocode, "incomplete", "?"); - } - - if ((afi != AFI_IP) && (afi != AFI_IP6)) { - vty_out(vty, "Afi %d not supported\n", afi); - return CMD_WARNING; - } - - for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; - rn = bgp_route_next(rn)) { - if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0) - continue; - - if ((table = rn->info) != NULL) { - rd_header = 1; - - for (rm = bgp_table_top(table); rm; - rm = bgp_route_next(rm)) { - total_count++; - if (use_json) - json_array = json_object_new_array(); - else - json_array = NULL; - - for (ri = rm->info; ri; ri = ri->next) { - if (type == bgp_show_type_neighbor) { - union sockunion *su = - output_arg; - - if (ri->peer->su_remote == NULL - || !sockunion_same( - ri->peer->su_remote, - su)) - continue; - } - if (header) { - if (use_json) { - if (!tags) { - json_object_int_add( - json, - "bgpTableVersion", - 0); - json_object_string_add( - json, - "bgpLocalRouterId", - inet_ntoa( - bgp->router_id)); - json_object_object_add( - json, - "bgpStatusCodes", - json_scode); - json_object_object_add( - json, - "bgpOriginCodes", - json_ocode); - } - } else { - if (tags) - vty_out(vty, - V4_HEADER_TAG); - else { - vty_out(vty, - "BGP table version is 0, local router ID is %s\n", - inet_ntoa( - bgp->router_id)); - vty_out(vty, - "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n"); - vty_out(vty, - "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"); - vty_out(vty, - V4_HEADER); - } - } - header = 0; - } - - if (rd_header) { - u_int16_t type; - struct rd_as rd_as; - struct rd_ip rd_ip = {0}; -#if ENABLE_BGP_VNC - struct rd_vnc_eth rd_vnc_eth = { - 0}; -#endif - u_char *pnt; - - pnt = rn->p.u.val; - - /* Decode RD type. */ - type = decode_rd_type(pnt); - /* Decode RD value. */ - if (type == RD_TYPE_AS) - decode_rd_as(pnt + 2, - &rd_as); - else if (type == RD_TYPE_AS4) - decode_rd_as4(pnt + 2, - &rd_as); - else if (type == RD_TYPE_IP) - decode_rd_ip(pnt + 2, - &rd_ip); -#if ENABLE_BGP_VNC - else if (type - == RD_TYPE_VNC_ETH) - decode_rd_vnc_eth( - pnt, - &rd_vnc_eth); -#endif - - if (use_json) { - char buffer[BUFSIZ]; - if (type == RD_TYPE_AS - || type == RD_TYPE_AS4) - sprintf(buffer, - "%u:%d", - rd_as.as, - rd_as.val); - else if (type - == RD_TYPE_IP) - sprintf(buffer, - "%s:%d", - inet_ntoa( - rd_ip.ip), - rd_ip.val); - json_object_string_add( - json_nroute, - "routeDistinguisher", - buffer); - } else { - vty_out(vty, - "Route Distinguisher: "); - - if (type == RD_TYPE_AS - || type == RD_TYPE_AS4) - vty_out(vty, - "%u:%d", - rd_as.as, - rd_as.val); - else if (type - == RD_TYPE_IP) - vty_out(vty, - "%s:%d", - inet_ntoa( - rd_ip.ip), - rd_ip.val); -#if ENABLE_BGP_VNC - else if ( - type - == RD_TYPE_VNC_ETH) - vty_out(vty, - "%u:%02x:%02x:%02x:%02x:%02x:%02x", - rd_vnc_eth - .local_nve_id, - rd_vnc_eth - .macaddr - .octet[0], - rd_vnc_eth - .macaddr - .octet[1], - rd_vnc_eth - .macaddr - .octet[2], - rd_vnc_eth - .macaddr - .octet[3], - rd_vnc_eth - .macaddr - .octet[4], - rd_vnc_eth - .macaddr - .octet[5]); -#endif - vty_out(vty, "\n"); - } - rd_header = 0; - } - if (tags) - route_vty_out_tag(vty, &rm->p, - ri, 0, - SAFI_MPLS_VPN, - json_array); - else - route_vty_out(vty, &rm->p, ri, - 0, SAFI_MPLS_VPN, - json_array); - output_count++; - } - - if (use_json) { - struct prefix *p; - char buf_a[BUFSIZ]; - char buf_b[BUFSIZ]; - p = &rm->p; - sprintf(buf_a, "%s/%d", - inet_ntop(p->family, - &p->u.prefix, buf_b, - BUFSIZ), - p->prefixlen); - json_object_object_add( - json_mroute, buf_a, json_array); - } - } - - if (use_json) { - struct prefix *p; - char buf_a[BUFSIZ]; - char buf_b[BUFSIZ]; - p = &rn->p; - sprintf(buf_a, "%s/%d", - inet_ntop(p->family, &p->u.prefix, - buf_b, BUFSIZ), - p->prefixlen); - json_object_object_add(json_nroute, buf_a, - json_mroute); - } - } - } - - if (use_json) { - json_object_object_add(json, "routes", json_nroute); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } else { - if (output_count == 0) - vty_out(vty, "No prefixes displayed, %ld exist\n", - total_count); - else - vty_out(vty, - "\nDisplayed %ld routes and %ld total paths\n", - output_count, total_count); - } - - return CMD_SUCCESS; + table = bgp->rib[afi][SAFI_MPLS_VPN]; + return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, + table, prd, type, output_arg, use_json); } DEFUN (show_bgp_ip_vpn_all_rd, show_bgp_ip_vpn_all_rd_cmd, "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]", SHOW_STR - IP_STR BGP_STR BGP_VPNVX_HELP_STR "Display VPN NLRI specific information\n" + "Display VPN NLRI specific information\n" "Display information for a route distinguisher\n" "VPN Route Distinguisher\n" JSON_STR) { - int idx_rd = 5; int ret; struct prefix_rd prd; afi_t afi; int idx = 0; if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) { - if (argc >= 7 && argv[idx_rd]->arg) { - ret = str2prefix_rd(argv[idx_rd]->arg, &prd); + if (argv_find(argv, argc, "rd", &idx)) { + ret = str2prefix_rd(argv[idx+1]->arg, &prd); if (!ret) { vty_out(vty, "%% Malformed Route Distinguisher\n"); @@ -668,9 +407,21 @@ DEFUN (show_bgp_ip_vpn_all_rd, return CMD_SUCCESS; } +ALIAS(show_bgp_ip_vpn_all_rd, + show_bgp_ip_vpn_rd_cmd, + "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]", + SHOW_STR + BGP_STR + BGP_VPNVX_HELP_STR + "Display VPN NLRI specific information\n" + "Display information for a route distinguisher\n" + "VPN Route Distinguisher\n" + JSON_STR) + +#ifdef KEEP_OLD_VPN_COMMANDS DEFUN (show_ip_bgp_vpn_rd, show_ip_bgp_vpn_rd_cmd, - "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN", + "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN", SHOW_STR IP_STR BGP_STR @@ -697,7 +448,6 @@ DEFUN (show_ip_bgp_vpn_rd, return CMD_SUCCESS; } -#ifdef KEEP_OLD_VPN_COMMANDS DEFUN (show_ip_bgp_vpn_all, show_ip_bgp_vpn_all_cmd, "show [ip] bgp <vpnv4|vpnv6>", @@ -1055,8 +805,9 @@ void bgp_mplsvpn_init(void) install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd); install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd); - install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd); + install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd); #ifdef KEEP_OLD_VPN_COMMANDS + install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd); install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd); install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd); install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3307f86088..0c2a2f6fe9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6500,246 +6500,258 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, /* Print attribute */ attr = binfo->attr; - if (attr) { - /* - * For ENCAP and EVPN routes, nexthop address family is not - * neccessarily the same as the prefix address family. - * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field - * EVPN routes are also exchanged with a MP nexthop. Currently, - * this - * is only IPv4, the value will be present in either - * attr->nexthop or - * attr->mp_nexthop_global_in - */ - if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) { - char buf[BUFSIZ]; - int af = NEXTHOP_FAMILY(attr->mp_nexthop_len); - - switch (af) { - case AF_INET: - vty_out(vty, "%s", - inet_ntop(af, - &attr->mp_nexthop_global_in, - buf, BUFSIZ)); - break; - case AF_INET6: - vty_out(vty, "%s", - inet_ntop(af, &attr->mp_nexthop_global, - buf, BUFSIZ)); - break; - default: - vty_out(vty, "?"); - break; - } - } else if (safi == SAFI_EVPN) { - if (json_paths) { - json_nexthop_global = json_object_new_object(); + if (!attr) { + if (json_paths) + json_object_array_add(json_paths, json_path); + else + vty_out(vty, "\n"); - json_object_string_add( - json_nexthop_global, "ip", - inet_ntoa(attr->nexthop)); - json_object_string_add(json_nexthop_global, - "afi", "ipv4"); - json_object_boolean_true_add( - json_nexthop_global, "used"); - } else - vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); + return; + } + + /* + * For ENCAP and EVPN routes, nexthop address family is not + * neccessarily the same as the prefix address family. + * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field + * EVPN routes are also exchanged with a MP nexthop. Currently, + * this + * is only IPv4, the value will be present in either + * attr->nexthop or + * attr->mp_nexthop_global_in + */ + if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) { + char buf[BUFSIZ]; + char nexthop[128]; + int af = NEXTHOP_FAMILY(attr->mp_nexthop_len); + + switch (af) { + case AF_INET: + sprintf(nexthop, "%s", + inet_ntop(af, &attr->mp_nexthop_global_in, + buf, BUFSIZ)); + break; + case AF_INET6: + sprintf(nexthop, "%s", + inet_ntop(af, &attr->mp_nexthop_global, + buf, BUFSIZ)); + break; + default: + sprintf(nexthop, "?"); + break; } - /* IPv4 Next Hop */ - else if (p->family == AF_INET - && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { - if (json_paths) { - json_nexthop_global = json_object_new_object(); - if ((safi == SAFI_MPLS_VPN) - || (safi == SAFI_EVPN)) - json_object_string_add( - json_nexthop_global, "ip", - inet_ntoa( - attr->mp_nexthop_global_in)); - else - json_object_string_add( - json_nexthop_global, "ip", - inet_ntoa(attr->nexthop)); + if (json_paths) { + json_nexthop_global = json_object_new_object(); + + json_object_string_add(json_nexthop_global, + "afi", + (af == AF_INET) ? + "ip" : "ipv6"); + json_object_string_add(json_nexthop_global, + (af == AF_INET) ? + "ip" : "ipv6", + nexthop); + json_object_boolean_true_add(json_nexthop_global, + "used"); + } else + vty_out(vty, "%s", nexthop); + } else if (safi == SAFI_EVPN) { + if (json_paths) { + json_nexthop_global = json_object_new_object(); + + json_object_string_add(json_nexthop_global, "ip", + inet_ntoa(attr->nexthop)); + json_object_string_add(json_nexthop_global, + "afi", "ipv4"); + json_object_boolean_true_add(json_nexthop_global, + "used"); + } else + vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); + } + /* IPv4 Next Hop */ + else if (p->family == AF_INET + && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + if (json_paths) { + json_nexthop_global = json_object_new_object(); + if ((safi == SAFI_MPLS_VPN) + || (safi == SAFI_EVPN)) json_object_string_add(json_nexthop_global, - "afi", "ipv4"); - json_object_boolean_true_add( - json_nexthop_global, "used"); - } else { - if ((safi == SAFI_MPLS_VPN) - || (safi == SAFI_EVPN)) - vty_out(vty, "%-16s", - inet_ntoa( - attr->mp_nexthop_global_in)); - else - vty_out(vty, "%-16s", - inet_ntoa(attr->nexthop)); - } + "ip", + inet_ntoa(attr->mp_nexthop_global_in)); + else + json_object_string_add(json_nexthop_global, + "ip", + inet_ntoa(attr->nexthop)); + + json_object_string_add(json_nexthop_global, + "afi", "ipv4"); + json_object_boolean_true_add(json_nexthop_global, + "used"); + } else { + if ((safi == SAFI_MPLS_VPN) + || (safi == SAFI_EVPN)) + vty_out(vty, "%-16s", + inet_ntoa( + attr->mp_nexthop_global_in)); + else + vty_out(vty, "%-16s", + inet_ntoa(attr->nexthop)); } + } - /* IPv6 Next Hop */ - else if (p->family == AF_INET6 - || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { - int len; - char buf[BUFSIZ]; + /* IPv6 Next Hop */ + else if (p->family == AF_INET6 + || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + int len; + char buf[BUFSIZ]; - if (json_paths) { - json_nexthop_global = json_object_new_object(); + if (json_paths) { + json_nexthop_global = json_object_new_object(); + json_object_string_add(json_nexthop_global, "ip", + inet_ntop(AF_INET6, + &attr->mp_nexthop_global, buf, + BUFSIZ)); + json_object_string_add(json_nexthop_global, + "afi", "ipv6"); + json_object_string_add(json_nexthop_global, + "scope", "global"); + + /* We display both LL & GL if both have been + * received */ + if ((attr->mp_nexthop_len == 32) + || (binfo->peer->conf_if)) { + json_nexthop_ll = + json_object_new_object(); json_object_string_add( - json_nexthop_global, "ip", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, buf, - BUFSIZ)); - json_object_string_add(json_nexthop_global, + json_nexthop_ll, "ip", + inet_ntop( + AF_INET6, + &attr->mp_nexthop_local, + buf, BUFSIZ)); + json_object_string_add(json_nexthop_ll, "afi", "ipv6"); - json_object_string_add(json_nexthop_global, - "scope", "global"); + json_object_string_add(json_nexthop_ll, + "scope", + "link-local"); - /* We display both LL & GL if both have been - * received */ - if ((attr->mp_nexthop_len == 32) - || (binfo->peer->conf_if)) { - json_nexthop_ll = - json_object_new_object(); - json_object_string_add( - json_nexthop_ll, "ip", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_local, - buf, BUFSIZ)); - json_object_string_add(json_nexthop_ll, - "afi", "ipv6"); - json_object_string_add(json_nexthop_ll, - "scope", - "link-local"); - - if ((IPV6_ADDR_CMP( - &attr->mp_nexthop_global, - &attr->mp_nexthop_local) - != 0) - && !attr->mp_nexthop_prefer_global) - json_object_boolean_true_add( - json_nexthop_ll, - "used"); - else - json_object_boolean_true_add( - json_nexthop_global, - "used"); - } else + if ((IPV6_ADDR_CMP( + &attr->mp_nexthop_global, + &attr->mp_nexthop_local) + != 0) + && !attr->mp_nexthop_prefer_global) json_object_boolean_true_add( - json_nexthop_global, "used"); - } else { - /* Display LL if LL/Global both in table unless - * prefer-global is set */ - if (((attr->mp_nexthop_len == 32) - && !attr->mp_nexthop_prefer_global) - || (binfo->peer->conf_if)) { - if (binfo->peer->conf_if) { - len = vty_out( - vty, "%s", - binfo->peer->conf_if); - len = 16 - len; /* len of IPv6 - addr + max - len of def - ifname */ - - if (len < 1) - vty_out(vty, "\n%*s", - 36, " "); - else - vty_out(vty, "%*s", len, - " "); - } else { - len = vty_out( - vty, "%s", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_local, - buf, BUFSIZ)); - len = 16 - len; - - if (len < 1) - vty_out(vty, "\n%*s", - 36, " "); - else - vty_out(vty, "%*s", len, - " "); - } + json_nexthop_ll, + "used"); + else + json_object_boolean_true_add( + json_nexthop_global, + "used"); + } else + json_object_boolean_true_add( + json_nexthop_global, "used"); + } else { + /* Display LL if LL/Global both in table unless + * prefer-global is set */ + if (((attr->mp_nexthop_len == 32) + && !attr->mp_nexthop_prefer_global) + || (binfo->peer->conf_if)) { + if (binfo->peer->conf_if) { + len = vty_out( + vty, "%s", + binfo->peer->conf_if); + len = 16 - len; /* len of IPv6 + addr + max + len of def + ifname */ + + if (len < 1) + vty_out(vty, "\n%*s", + 36, " "); + else + vty_out(vty, "%*s", len, + " "); } else { len = vty_out( vty, "%s", inet_ntop( AF_INET6, - &attr->mp_nexthop_global, + &attr->mp_nexthop_local, buf, BUFSIZ)); len = 16 - len; if (len < 1) - vty_out(vty, "\n%*s", 36, " "); + vty_out(vty, "\n%*s", + 36, " "); else - vty_out(vty, "%*s", len, " "); + vty_out(vty, "%*s", len, + " "); } + } else { + len = vty_out(vty, "%s", + inet_ntop(AF_INET6, + &attr->mp_nexthop_global, + buf, BUFSIZ)); + len = 16 - len; + + if (len < 1) + vty_out(vty, "\n%*s", 36, " "); + else + vty_out(vty, "%*s", len, " "); } } + } - /* MED/Metric */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) - if (json_paths) - json_object_int_add(json_path, "med", - attr->med); - else - vty_out(vty, "%10u", attr->med); - else if (!json_paths) - vty_out(vty, " "); - - /* Local Pref */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) - if (json_paths) - json_object_int_add(json_path, "localpref", - attr->local_pref); - else - vty_out(vty, "%7u", attr->local_pref); - else if (!json_paths) - vty_out(vty, " "); + /* MED/Metric */ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) + if (json_paths) + json_object_int_add(json_path, "med", + attr->med); + else + vty_out(vty, "%10u", attr->med); + else if (!json_paths) + vty_out(vty, " "); + /* Local Pref */ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) if (json_paths) - json_object_int_add(json_path, "weight", attr->weight); + json_object_int_add(json_path, "localpref", + attr->local_pref); else - vty_out(vty, "%7u ", attr->weight); + vty_out(vty, "%7u", attr->local_pref); + else if (!json_paths) + vty_out(vty, " "); - if (json_paths) { - char buf[BUFSIZ]; - json_object_string_add(json_path, "peerId", - sockunion2str(&binfo->peer->su, - buf, - SU_ADDRSTRLEN)); - } + if (json_paths) + json_object_int_add(json_path, "weight", attr->weight); + else + vty_out(vty, "%7u ", attr->weight); - /* Print aspath */ - if (attr->aspath) { - if (json_paths) - json_object_string_add(json_path, "aspath", - attr->aspath->str); - else - aspath_print_vty(vty, "%s", attr->aspath, " "); - } + if (json_paths) { + char buf[BUFSIZ]; + json_object_string_add(json_path, "peerId", + sockunion2str(&binfo->peer->su, + buf, + SU_ADDRSTRLEN)); + } - /* Print origin */ + /* Print aspath */ + if (attr->aspath) { if (json_paths) - json_object_string_add( - json_path, "origin", - bgp_origin_long_str[attr->origin]); + json_object_string_add(json_path, "aspath", + attr->aspath->str); else - vty_out(vty, "%s", bgp_origin_str[attr->origin]); - } else { - if (json_paths) - json_object_string_add(json_path, "alert", - "No attributes"); - else - vty_out(vty, "No attributes to print\n"); + aspath_print_vty(vty, "%s", attr->aspath, " "); } + /* Print origin */ + if (json_paths) + json_object_string_add( + json_path, "origin", + bgp_origin_long_str[attr->origin]); + else + vty_out(vty, "%s", bgp_origin_str[attr->origin]); + if (json_paths) { if (json_nexthop_global || json_nexthop_ll) { json_nexthops = json_object_new_array(); @@ -8122,23 +8134,29 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, safi_t safi); -static int bgp_show_table(struct vty *vty, struct bgp *bgp, + +static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, u_char use_json) + void *output_arg, u_char use_json, + char *rd, int is_last, + unsigned long *output_cum, unsigned long *total_cum) { struct bgp_info *ri; struct bgp_node *rn; int header = 1; int display; - unsigned long output_count; - unsigned long total_count; + unsigned long output_count = 0; + unsigned long total_count = 0; struct prefix *p; char buf[BUFSIZ]; char buf2[BUFSIZ]; json_object *json_paths = NULL; int first = 1; - if (use_json) { + if (output_cum && *output_cum != 0) + header = 0; + + if (use_json && header) { vty_out(vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ", @@ -8146,252 +8164,290 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name, table->version, inet_ntoa(bgp->router_id)); + if (rd) + vty_out(vty, " \"routeDistinguishers\" : {"); json_paths = json_object_new_object(); } - /* This is first entry point, so reset total line. */ - output_count = 0; - total_count = 0; + if (use_json && rd) { + vty_out(vty, " \"%s\" : { ", rd); + } /* Start processing of routes. */ - for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) - if (rn->info != NULL) { - display = 0; - if (!first && use_json) { - vty_out(vty, ","); - } - if (use_json) - json_paths = json_object_new_array(); - else - json_paths = NULL; + for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { + if (rn->info == NULL) + continue; - for (ri = rn->info; ri; ri = ri->next) { - total_count++; - if (type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_neighbor - || type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) { - if (!(ri->extra - && ri->extra->damp_info)) - continue; - } - if (type == bgp_show_type_regexp) { - regex_t *regex = output_arg; + display = 0; + if (!first && use_json) + vty_out(vty, ","); + if (use_json) + json_paths = json_object_new_array(); + else + json_paths = NULL; - if (bgp_regexec(regex, ri->attr->aspath) - == REG_NOMATCH) - continue; - } - if (type == bgp_show_type_prefix_list) { - struct prefix_list *plist = output_arg; + for (ri = rn->info; ri; ri = ri->next) { + total_count++; + if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_neighbor + || type == bgp_show_type_dampend_paths + || type == bgp_show_type_damp_neighbor) { + if (!(ri->extra + && ri->extra->damp_info)) + continue; + } + if (type == bgp_show_type_regexp) { + regex_t *regex = output_arg; - if (prefix_list_apply(plist, &rn->p) - != PREFIX_PERMIT) - continue; - } - if (type == bgp_show_type_filter_list) { - struct as_list *as_list = output_arg; + if (bgp_regexec(regex, ri->attr->aspath) + == REG_NOMATCH) + continue; + } + if (type == bgp_show_type_prefix_list) { + struct prefix_list *plist = output_arg; - if (as_list_apply(as_list, - ri->attr->aspath) - != AS_FILTER_PERMIT) - continue; - } - if (type == bgp_show_type_route_map) { - struct route_map *rmap = output_arg; - struct bgp_info binfo; - struct attr dummy_attr; - int ret; + if (prefix_list_apply(plist, &rn->p) + != PREFIX_PERMIT) + continue; + } + if (type == bgp_show_type_filter_list) { + struct as_list *as_list = output_arg; - bgp_attr_dup(&dummy_attr, ri->attr); + if (as_list_apply(as_list, ri->attr->aspath) + != AS_FILTER_PERMIT) + continue; + } + if (type == bgp_show_type_route_map) { + struct route_map *rmap = output_arg; + struct bgp_info binfo; + struct attr dummy_attr; + int ret; - binfo.peer = ri->peer; - binfo.attr = &dummy_attr; + bgp_attr_dup(&dummy_attr, ri->attr); - ret = route_map_apply(rmap, &rn->p, - RMAP_BGP, &binfo); - if (ret == RMAP_DENYMATCH) - continue; - } - if (type == bgp_show_type_neighbor - || type == bgp_show_type_flap_neighbor - || type == bgp_show_type_damp_neighbor) { - union sockunion *su = output_arg; - - if (ri->peer == NULL - || ri->peer->su_remote == NULL - || !sockunion_same( - ri->peer->su_remote, su)) - continue; - } - if (type == bgp_show_type_cidr_only) { - u_int32_t destination; + binfo.peer = ri->peer; + binfo.attr = &dummy_attr; - destination = - ntohl(rn->p.u.prefix4.s_addr); - if (IN_CLASSC(destination) - && rn->p.prefixlen == 24) - continue; - if (IN_CLASSB(destination) - && rn->p.prefixlen == 16) - continue; - if (IN_CLASSA(destination) - && rn->p.prefixlen == 8) - continue; - } - if (type == bgp_show_type_prefix_longer) { - struct prefix *p = output_arg; + ret = route_map_apply(rmap, &rn->p, + RMAP_BGP, &binfo); + if (ret == RMAP_DENYMATCH) + continue; + } + if (type == bgp_show_type_neighbor + || type == bgp_show_type_flap_neighbor + || type == bgp_show_type_damp_neighbor) { + union sockunion *su = output_arg; + + if (ri->peer == NULL + || ri->peer->su_remote == NULL + || !sockunion_same(ri->peer->su_remote, + su)) + continue; + } + if (type == bgp_show_type_cidr_only) { + u_int32_t destination; - if (!prefix_match(p, &rn->p)) - continue; - } - if (type == bgp_show_type_community_all) { - if (!ri->attr->community) - continue; - } - if (type == bgp_show_type_community) { - struct community *com = output_arg; + destination = ntohl(rn->p.u.prefix4.s_addr); + if (IN_CLASSC(destination) + && rn->p.prefixlen == 24) + continue; + if (IN_CLASSB(destination) + && rn->p.prefixlen == 16) + continue; + if (IN_CLASSA(destination) + && rn->p.prefixlen == 8) + continue; + } + if (type == bgp_show_type_prefix_longer) { + struct prefix *p = output_arg; - if (!ri->attr->community - || !community_match( - ri->attr->community, - com)) - continue; - } - if (type == bgp_show_type_community_exact) { - struct community *com = output_arg; + if (!prefix_match(p, &rn->p)) + continue; + } + if (type == bgp_show_type_community_all) { + if (!ri->attr->community) + continue; + } + if (type == bgp_show_type_community) { + struct community *com = output_arg; - if (!ri->attr->community - || !community_cmp( - ri->attr->community, - com)) - continue; - } - if (type == bgp_show_type_community_list) { - struct community_list *list = - output_arg; + if (!ri->attr->community + || !community_match(ri->attr->community, + com)) + continue; + } + if (type == bgp_show_type_community_exact) { + struct community *com = output_arg; - if (!community_list_match( - ri->attr->community, list)) - continue; - } - if (type - == bgp_show_type_community_list_exact) { - struct community_list *list = - output_arg; + if (!ri->attr->community + || !community_cmp(ri->attr->community, + com)) + continue; + } + if (type == bgp_show_type_community_list) { + struct community_list *list = output_arg; - if (!community_list_exact_match( - ri->attr->community, list)) - continue; - } - if (type == bgp_show_type_lcommunity) { - struct lcommunity *lcom = output_arg; + if (!community_list_match( + ri->attr->community, list)) + continue; + } + if (type + == bgp_show_type_community_list_exact) { + struct community_list *list = output_arg; - if (!ri->attr->lcommunity - || !lcommunity_match( - ri->attr->lcommunity, - lcom)) - continue; - } - if (type == bgp_show_type_lcommunity_list) { - struct community_list *list = - output_arg; + if (!community_list_exact_match( + ri->attr->community, list)) + continue; + } + if (type == bgp_show_type_lcommunity) { + struct lcommunity *lcom = output_arg; - if (!lcommunity_list_match( - ri->attr->lcommunity, list)) - continue; - } - if (type == bgp_show_type_lcommunity_all) { - if (!ri->attr->lcommunity) - continue; - } - if (type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) { - if (!CHECK_FLAG(ri->flags, - BGP_INFO_DAMPED) - || CHECK_FLAG(ri->flags, - BGP_INFO_HISTORY)) - continue; - } + if (!ri->attr->lcommunity + || !lcommunity_match(ri->attr->lcommunity, + lcom)) + continue; + } + if (type == bgp_show_type_lcommunity_list) { + struct community_list *list = output_arg; - if (!use_json && header) { - vty_out(vty, - "BGP table version is %" PRIu64 - ", local router ID is %s\n", - table->version, - inet_ntoa(bgp->router_id)); - vty_out(vty, BGP_SHOW_SCODE_HEADER); - vty_out(vty, BGP_SHOW_OCODE_HEADER); - if (type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) - vty_out(vty, - BGP_SHOW_DAMP_HEADER); - else if ( - type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_neighbor) - vty_out(vty, - BGP_SHOW_FLAP_HEADER); - else - vty_out(vty, BGP_SHOW_HEADER); - header = 0; - } + if (!lcommunity_list_match( + ri->attr->lcommunity, list)) + continue; + } + if (type == bgp_show_type_lcommunity_all) { + if (!ri->attr->lcommunity) + continue; + } + if (type == bgp_show_type_dampend_paths + || type == bgp_show_type_damp_neighbor) { + if (!CHECK_FLAG(ri->flags, BGP_INFO_DAMPED) + || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) + continue; + } + if (!use_json && header) { + vty_out(vty, + "BGP table version is %" PRIu64 + ", local router ID is %s\n", + table->version, + inet_ntoa(bgp->router_id)); + vty_out(vty, BGP_SHOW_SCODE_HEADER); + vty_out(vty, BGP_SHOW_OCODE_HEADER); if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) - damp_route_vty_out( - vty, &rn->p, ri, display, - SAFI_UNICAST, use_json, - json_paths); - else if (type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_neighbor) - flap_route_vty_out( - vty, &rn->p, ri, display, - SAFI_UNICAST, use_json, - json_paths); + vty_out(vty, BGP_SHOW_DAMP_HEADER); + else if ( + type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_neighbor) + vty_out(vty, BGP_SHOW_FLAP_HEADER); else - route_vty_out(vty, &rn->p, ri, display, - SAFI_UNICAST, json_paths); - display++; + vty_out(vty, BGP_SHOW_HEADER); + header = 0; } - - if (display) { - output_count++; - if (use_json) { - p = &rn->p; - sprintf(buf2, "%s/%d", - inet_ntop(p->family, - &p->u.prefix, buf, - BUFSIZ), - p->prefixlen); - vty_out(vty, "\"%s\": ", buf2); - vty_out(vty, "%s", - json_object_to_json_string( - json_paths)); - json_object_free(json_paths); - first = 0; - } + if (rd != NULL && !display && !output_count) { + if (!use_json) + vty_out(vty, + "Route Distinguisher: %s\n", + rd); } + if (type == bgp_show_type_dampend_paths + || type == bgp_show_type_damp_neighbor) + damp_route_vty_out(vty, &rn->p, ri, display, + safi, use_json, + json_paths); + else if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_neighbor) + flap_route_vty_out(vty, &rn->p, ri, display, + safi, use_json, + json_paths); + else + route_vty_out(vty, &rn->p, ri, display, + safi, json_paths); + display++; } + if (display) { + output_count++; + if (!use_json) + continue; + + p = &rn->p; + sprintf(buf2, "%s/%d", + inet_ntop(p->family, &p->u.prefix, + buf, BUFSIZ), + p->prefixlen); + vty_out(vty, "\"%s\": ", buf2); + vty_out(vty, "%s", + json_object_to_json_string(json_paths)); + json_object_free(json_paths); + first = 0; + } + } + + if (output_cum) { + output_count += *output_cum; + *output_cum = output_count; + } + if (total_cum) { + total_count += *total_cum; + *total_cum = total_count; + } if (use_json) { json_object_free(json_paths); - vty_out(vty, " } }\n"); + if (is_last) + vty_out(vty, " } }\n"); + else + vty_out(vty, " }, "); } else { - /* No route is displayed */ - if (output_count == 0) { - if (type == bgp_show_type_normal) + if (is_last) { + /* No route is displayed */ + if (output_count == 0) { + if (type == bgp_show_type_normal) + vty_out(vty, + "No BGP prefixes displayed, %ld exist\n", + total_count); + } else vty_out(vty, - "No BGP prefixes displayed, %ld exist\n", - total_count); - } else - vty_out(vty, - "\nDisplayed %ld routes and %ld total paths\n", - output_count, total_count); + "\nDisplayed %ld routes and %ld total paths\n", + output_count, total_count); + } } return CMD_SUCCESS; } +int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, + struct bgp_table *table, struct prefix_rd *prd_match, + enum bgp_show_type type, void *output_arg, + u_char use_json) +{ + struct bgp_node *rn, *next; + unsigned long output_cum = 0; + unsigned long total_cum = 0; + + for (rn = bgp_table_top(table); rn; rn = next) { + next = bgp_route_next(rn); + if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0) + continue; + if (rn->info != NULL) { + struct prefix_rd prd; + char rd[BUFSIZ]; + + memcpy(&prd, &(rn->p), sizeof(struct prefix_rd)); + if (prefix_rd2str(&prd, rd, BUFSIZ) == NULL) + sprintf(rd, + "Unknown Type: %u", + decode_rd_type(prd.val)); + bgp_show_table(vty, bgp, safi, rn->info, type, + output_arg, use_json, + rd, next == NULL, + &output_cum, &total_cum); + } + } + if (use_json) + vty_out(vty, " } }"); + return CMD_SUCCESS; +} static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, enum bgp_show_type type, void *output_arg, u_char use_json) { @@ -8409,18 +8465,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, return CMD_WARNING; } + table = bgp->rib[afi][safi]; /* use MPLS and ENCAP specific shows until they are merged */ if (safi == SAFI_MPLS_VPN) { - return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0, - use_json); + return bgp_show_table_rd(vty, bgp, safi, table, NULL, type, + output_arg, use_json); } /* labeled-unicast routes live in the unicast table */ else if (safi == SAFI_LABELED_UNICAST) safi = SAFI_UNICAST; - table = bgp->rib[afi][safi]; - - return bgp_show_table(vty, bgp, table, type, output_arg, use_json); + return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, + NULL, 1, NULL, NULL); } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, @@ -9090,12 +9146,7 @@ DEFUN (show_ip_bgp_json, return bgp_show(vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj); } - - if (safi == SAFI_MPLS_VPN) - return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal, - NULL, 0, uj); - else - return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj); + return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj); } DEFUN (show_ip_bgp_route, @@ -11413,12 +11464,6 @@ void bgp_route_init(void) install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd); install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd); - install_element(BGP_IPV6L_NODE, &bgp_table_map_cmd); - install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd); - install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd); - install_element(BGP_IPV6L_NODE, &no_bgp_table_map_cmd); - install_element(BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd); - install_element(BGP_NODE, &bgp_distance_cmd); install_element(BGP_NODE, &no_bgp_distance_cmd); install_element(BGP_NODE, &bgp_distance_source_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 6caa1c8939..6fbeed8963 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -442,4 +442,8 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, struct bgp_info *binfo, afi_t afi, safi_t safi, json_object *json_paths); +extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, + struct bgp_table *table, struct prefix_rd *prd, + enum bgp_show_type type, void *output_arg, + u_char use_json); #endif /* _QUAGGA_BGP_ROUTE_H */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4ddb499821..c41039e7c1 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -6045,7 +6045,13 @@ DEFUN_NOSH (address_family_ipv4_safi, { if (argc == 3) { + VTY_DECLVAR_CONTEXT(bgp, bgp); safi_t safi = bgp_vty_safi_from_str(argv[2]->text); + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && + safi != SAFI_UNICAST && safi != SAFI_MULTICAST) { + vty_out(vty, "Only Unicast and Multicast SAFIs supported in non-core instances.\n"); + return CMD_WARNING_CONFIG_FAILED; + } vty->node = bgp_node_type(AFI_IP, safi); } else vty->node = BGP_IPV4_NODE; @@ -6061,7 +6067,13 @@ DEFUN_NOSH (address_family_ipv6_safi, BGP_SAFI_WITH_LABEL_HELP_STR) { if (argc == 3) { + VTY_DECLVAR_CONTEXT(bgp, bgp); safi_t safi = bgp_vty_safi_from_str(argv[2]->text); + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && + safi != SAFI_UNICAST && safi != SAFI_MULTICAST) { + vty_out(vty, "Only Unicast and Multicast SAFIs supported in non-core instances.\n"); + return CMD_WARNING_CONFIG_FAILED; + } vty->node = bgp_node_type(AFI_IP6, safi); } else vty->node = BGP_IPV6_NODE; @@ -6100,6 +6112,11 @@ DEFUN_NOSH (address_family_evpn, "Address Family\n" "Address Family modifier\n") { + VTY_DECLVAR_CONTEXT(bgp, bgp); + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) { + vty_out(vty, "Only Unicast and Multicast SAFIs supported in non-core instances.\n"); + return CMD_WARNING_CONFIG_FAILED; + } vty->node = BGP_EVPN_NODE; return CMD_SUCCESS; } @@ -6652,6 +6669,48 @@ DEFUN (show_bgp_memory, return CMD_SUCCESS; } +static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json) +{ + json_object *bestpath = json_object_new_object(); + + if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE)) + json_object_string_add(bestpath, "asPath", "ignore"); + + if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED)) + json_object_string_add(bestpath, "asPath", "confed"); + + if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { + if (bgp_flag_check(bgp, + BGP_FLAG_MULTIPATH_RELAX_AS_SET)) + json_object_string_add(bestpath, + "multiPathRelax", + "as-set"); + else + json_object_string_add(bestpath, + "multiPathRelax", + "true"); + } else + json_object_string_add(bestpath, + "multiPathRelax", + "false"); + + if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)) + json_object_string_add(bestpath, "compareRouterId", "true"); + if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) + || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) { + if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)) + json_object_string_add(bestpath, "med", + "confed"); + if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) + json_object_string_add(bestpath, "med", + "missing-as-worst"); + else + json_object_string_add(bestpath, "med", "true"); + } + + json_object_object_add(json, "bestPath", bestpath); +} + /* Show BGP peer's summary information. */ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, u_char use_json, json_object *json) @@ -7048,6 +7107,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_int_add(json, "totalPeers", count); json_object_int_add(json, "dynamicPeers", dn_count); + bgp_show_bestpath_json(bgp, json); + vty_out(vty, "%s\n", json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); @@ -9745,6 +9806,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, } if (use_json) { + bgp_show_bestpath_json(bgp, json); vty_out(vty, "%s\n", json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); @@ -9868,17 +9930,13 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name, /* "show [ip] bgp neighbors" commands. */ DEFUN (show_ip_bgp_neighbors, show_ip_bgp_neighbors_cmd, - "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:NN_OR_IP-ADDRESS:NN>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]", SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR "Address Family\n" "Address Family\n" - "Address Family\n" - "Display information about all VPNv4 NLRIs\n" - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index bc69b67de9..ddf461f1b1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -224,6 +224,10 @@ static int bgp_interface_delete(int command, struct zclient *zclient, struct interface *ifp; struct bgp *bgp; + bgp = bgp_lookup_by_vrf_id(vrf_id); + if (!bgp) + return 0; + s = zclient->ibuf; ifp = zebra_interface_state_read(s, vrf_id); if (!ifp) /* This may happen if we've just unregistered for a VRF. */ @@ -232,13 +236,9 @@ static int bgp_interface_delete(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name); - bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; - bgp_update_interface_nbrs(bgp, ifp, NULL); - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } @@ -252,6 +252,10 @@ static int bgp_interface_up(int command, struct zclient *zclient, struct listnode *node, *nnode; struct bgp *bgp; + bgp = bgp_lookup_by_vrf_id(vrf_id); + if (!bgp) + return 0; + s = zclient->ibuf; ifp = zebra_interface_state_read(s, vrf_id); @@ -261,10 +265,6 @@ static int bgp_interface_up(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name); - bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; - for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) bgp_connected_add(bgp, c); @@ -284,6 +284,10 @@ static int bgp_interface_down(int command, struct zclient *zclient, struct listnode *node, *nnode; struct bgp *bgp; + bgp = bgp_lookup_by_vrf_id(vrf_id); + if (!bgp) + return 0; + s = zclient->ibuf; ifp = zebra_interface_state_read(s, vrf_id); if (!ifp) @@ -292,10 +296,6 @@ static int bgp_interface_down(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name); - bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; - for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) bgp_connected_delete(bgp, c); @@ -338,6 +338,11 @@ static int bgp_interface_address_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *ifc; + struct bgp *bgp; + + bgp = bgp_lookup_by_vrf_id(vrf_id); + if (!bgp) + return 0; ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id); @@ -352,13 +357,8 @@ static int bgp_interface_address_add(int command, struct zclient *zclient, } if (if_is_operative(ifc->ifp)) { - struct bgp *bgp; - - bgp = bgp_lookup_by_vrf_id(vrf_id); - if (!bgp) - return 0; - bgp_connected_add(bgp, ifc); + /* If we have learnt of any neighbors on this interface, * check to kick off any BGP interface-based neighbors, * but only if this is a link-local address. @@ -377,6 +377,10 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient, struct connected *ifc; struct bgp *bgp; + bgp = bgp_lookup_by_vrf_id(vrf_id); + if (!bgp) + return 0; + ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id); if (ifc == NULL) @@ -390,9 +394,7 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient, } if (if_is_operative(ifc->ifp)) { - bgp = bgp_lookup_by_vrf_id(vrf_id); - if (bgp) - bgp_connected_delete(bgp, ifc); + bgp_connected_delete(bgp, ifc); } connected_free(ifc); @@ -591,18 +593,22 @@ static int zebra_read_route(int command, struct zclient *zclient, struct interface *if_lookup_by_ipv4(struct in_addr *addr, vrf_id_t vrf_id) { - struct listnode *ifnode; + struct vrf *vrf; struct listnode *cnode; struct interface *ifp; struct connected *connected; struct prefix_ipv4 p; struct prefix *cp; + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + p.family = AF_INET; p.prefix = *addr; p.prefixlen = IPV4_MAX_BITLEN; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) { cp = connected->address; @@ -616,13 +622,17 @@ struct interface *if_lookup_by_ipv4(struct in_addr *addr, vrf_id_t vrf_id) struct interface *if_lookup_by_ipv4_exact(struct in_addr *addr, vrf_id_t vrf_id) { - struct listnode *ifnode; + struct vrf *vrf; struct listnode *cnode; struct interface *ifp; struct connected *connected; struct prefix *cp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), ifnode, ifp)) { + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) { cp = connected->address; @@ -637,18 +647,22 @@ struct interface *if_lookup_by_ipv4_exact(struct in_addr *addr, vrf_id_t vrf_id) struct interface *if_lookup_by_ipv6(struct in6_addr *addr, ifindex_t ifindex, vrf_id_t vrf_id) { - struct listnode *ifnode; + struct vrf *vrf; struct listnode *cnode; struct interface *ifp; struct connected *connected; struct prefix_ipv6 p; struct prefix *cp; + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + p.family = AF_INET6; p.prefix = *addr; p.prefixlen = IPV6_MAX_BITLEN; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) { cp = connected->address; @@ -669,13 +683,17 @@ struct interface *if_lookup_by_ipv6(struct in6_addr *addr, ifindex_t ifindex, struct interface *if_lookup_by_ipv6_exact(struct in6_addr *addr, ifindex_t ifindex, vrf_id_t vrf_id) { - struct listnode *ifnode; + struct vrf *vrf; struct listnode *cnode; struct interface *ifp; struct connected *connected; struct prefix *cp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), ifnode, ifp)) { + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) { cp = connected->address; @@ -1290,10 +1308,8 @@ static void bgp_redist_del(struct bgp *bgp, afi_t afi, u_char type, if (red) { listnode_delete(bgp->redist[afi][type], red); XFREE(MTYPE_BGP_REDIST, red); - if (!bgp->redist[afi][type]->count) { - list_free(bgp->redist[afi][type]); - bgp->redist[afi][type] = NULL; - } + if (!bgp->redist[afi][type]->count) + list_delete_and_null(&bgp->redist[afi][type]); } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 54155290d6..d223cecc59 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2436,14 +2436,14 @@ int peer_group_delete(struct peer_group *group) peer_delete(other); } } - list_delete(group->peer); + list_delete_and_null(&group->peer); for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) { prefix_free(prefix); } - list_delete(group->listen_range[afi]); + list_delete_and_null(&group->listen_range[afi]); } XFREE(MTYPE_PEER_GROUP_HOST, group->name); @@ -3193,8 +3193,8 @@ void bgp_free(struct bgp *bgp) QOBJ_UNREG(bgp); - list_delete(bgp->group); - list_delete(bgp->peer); + list_delete_and_null(&bgp->group); + list_delete_and_null(&bgp->peer); if (bgp->peerhash) { hash_free(bgp->peerhash); @@ -7342,13 +7342,13 @@ void bgp_master_init(struct thread_master *master) */ static void bgp_if_finish(struct bgp *bgp) { - struct listnode *ifnode, *ifnnode; + struct vrf *vrf = vrf_lookup_by_id(bgp->vrf_id); struct interface *ifp; - if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) + if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW || !vrf) return; - for (ALL_LIST_ELEMENTS(vrf_iflist(bgp->vrf_id), ifnode, ifnnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct listnode *c_node, *c_nnode; struct connected *c; @@ -7454,8 +7454,7 @@ void bgp_terminate(void) /* reverse bgp_master_init */ bgp_close(); if (bm->listen_sockets) - list_free(bm->listen_sockets); - bm->listen_sockets = NULL; + list_delete_and_null(&bm->listen_sockets); for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 3dffb59d11..e82ca3bbbe 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -231,7 +231,7 @@ void *rfapi_get_rfp_start_val(void *bgpv) /*------------------------------------------ * bgp_rfapi_is_vnc_configured * - * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured + * Returns if VNC is configured * * input: * bgp NULL (=use default instance) @@ -240,6 +240,7 @@ void *rfapi_get_rfp_start_val(void *bgpv) * * return value: If VNC is configured for the bgpd instance * 0 Success + * EPERM Not Default instance (VNC operations not allowed) * ENXIO VNC not configured --------------------------------------------*/ int bgp_rfapi_is_vnc_configured(struct bgp *bgp) @@ -247,29 +248,32 @@ int bgp_rfapi_is_vnc_configured(struct bgp *bgp) if (bgp == NULL) bgp = bgp_get_default(); - if (bgp && bgp->rfapi_cfg) { - struct peer *peer; - struct peer_group *group; - struct listnode *node, *nnode; - /* if have configured VPN neighbors, assume running VNC */ - for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) { - if (group->conf->afc[AFI_IP][SAFI_MPLS_VPN] - || group->conf->afc[AFI_IP6][SAFI_MPLS_VPN]) - return 0; - } - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (peer->afc[AFI_IP][SAFI_MPLS_VPN] - || peer->afc[AFI_IP6][SAFI_MPLS_VPN]) - return 0; - } - } + if (bgp && bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) + return EPERM; + + if (bgp && bgp->rfapi_cfg) + return 0; return ENXIO; } /*********************************************************************** * VNC Configuration/CLI ***********************************************************************/ - +#define VNC_VTY_CONFIG_CHECK(bgp) \ + { \ + switch (bgp_rfapi_is_vnc_configured(bgp)) { \ + case EPERM: \ + vty_out(vty, "VNC operations only permitted on default BGP instance.\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + break; \ + case ENXIO: \ + vty_out(vty, "VNC not configured.\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + break; \ + default: \ + break; \ + } \ + } DEFUN (vnc_advertise_un_method, vnc_advertise_un_method_cmd, @@ -279,12 +283,7 @@ DEFUN (vnc_advertise_un_method, "Via Tunnel Encap attribute (in VPN SAFI)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp->rfapi_cfg) { - vty_out(vty, "VNC not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - + VNC_VTY_CONFIG_CHECK(bgp); if (!strncmp(argv[2]->arg, "encap-safi", 7)) { bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; @@ -301,9 +300,15 @@ DEFUN (vnc_advertise_un_method, DEFUN_NOSH (vnc_defaults, - vnc_defaults_cmd, - "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n") + vnc_defaults_cmd, + "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n") { + VTY_DECLVAR_CONTEXT(bgp, bgp); + VNC_VTY_CONFIG_CHECK(bgp); + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) { + vty_out(vty, "Malformed community-list value\n"); + return CMD_WARNING_CONFIG_FAILED; + } vty->node = BGP_VNC_DEFAULTS_NODE; return CMD_SUCCESS; } @@ -736,10 +741,7 @@ DEFUN (vnc_redistribute_rh_roo_localadmin, uint32_t localadmin; char *endptr; - if (!bgp->rfapi_cfg) { - vty_out(vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); localadmin = strtoul(argv[4]->arg, &endptr, 0); if (!argv[4]->arg[0] || *endptr) { @@ -787,11 +789,7 @@ DEFUN (vnc_redistribute_mode, VTY_DECLVAR_CONTEXT(bgp, bgp); vnc_redist_mode_t newmode; - if (!bgp->rfapi_cfg) { - vty_out(vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - + VNC_VTY_CONFIG_CHECK(bgp); switch (argv[3]->arg[0]) { case 'n': @@ -839,10 +837,7 @@ DEFUN (vnc_redistribute_protocol, int type = ZEBRA_ROUTE_MAX; /* init to bogus value */ afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); if (rfapi_str2route_type(argv[2]->arg, argv[3]->arg, &afi, &type)) { vty_out(vty, "%% Invalid route type\n"); @@ -884,10 +879,7 @@ DEFUN (vnc_no_redistribute_protocol, int type; afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); if (rfapi_str2route_type(argv[3]->arg, argv[4]->arg, &afi, &type)) { vty_out(vty, "%% Invalid route type\n"); @@ -921,10 +913,7 @@ DEFUN (vnc_redistribute_bgp_exterior, int type; afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); if (rfapi_str2route_type(argv[2]->arg, "bgp-direct-to-nve-groups", &afi, &type)) { @@ -952,11 +941,7 @@ DEFUN (vnc_redistribute_nvegroup, "NVE group\n" "Group name\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); vnc_redistribute_prechange(bgp); @@ -985,10 +970,7 @@ DEFUN (vnc_redistribute_no_nvegroup, { VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); vnc_redistribute_prechange(bgp); @@ -1013,11 +995,7 @@ DEFUN (vnc_redistribute_lifetime, "Allow lifetime to never expire\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); vnc_redistribute_prechange(bgp); @@ -1051,10 +1029,8 @@ DEFUN (vnc_redist_bgpdirect_no_prefixlist, struct rfapi_cfg *hc; uint8_t route_type = 0; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (strmatch(argv[3]->text, "bgp-direct")) { route_type = ZEBRA_ROUTE_BGP_DIRECT; @@ -1097,10 +1073,8 @@ DEFUN (vnc_redist_bgpdirect_prefixlist, afi_t afi; uint8_t route_type = 0; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (strmatch(argv[2]->text, "bgp-direct")) { route_type = ZEBRA_ROUTE_BGP_DIRECT; @@ -1141,10 +1115,8 @@ DEFUN (vnc_redist_bgpdirect_no_routemap, struct rfapi_cfg *hc; uint8_t route_type = 0; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (strmatch(argv[3]->text, "bgp-direct")) { route_type = ZEBRA_ROUTE_BGP_DIRECT; @@ -1177,10 +1149,8 @@ DEFUN (vnc_redist_bgpdirect_routemap, struct rfapi_cfg *hc; uint8_t route_type = 0; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (strmatch(argv[2]->text, "bgp-direct")) { route_type = ZEBRA_ROUTE_BGP_DIRECT; @@ -1219,10 +1189,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist, VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg) afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1263,10 +1230,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist, VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1306,10 +1270,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap, VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1340,10 +1301,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_routemap, VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1388,10 +1346,7 @@ DEFUN (vnc_export_mode, uint32_t oldmode = 0; uint32_t newmode = 0; - if (!bgp->rfapi_cfg) { - vty_out(vty, "VNC not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); if (argv[2]->arg[0] == 'b') { oldmode = bgp->rfapi_cfg->flags @@ -1499,10 +1454,7 @@ DEFUN (vnc_export_nvegroup, VTY_DECLVAR_CONTEXT(bgp, bgp); struct rfapi_nve_group_cfg *rfg_new; - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg, RFAPI_GROUP_CFG_NVE); @@ -1596,10 +1548,7 @@ DEFUN (vnc_no_export_nvegroup, struct listnode *node, *nnode; struct rfapi_rfg_name *rfgn; - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); if (argv[2]->arg[0] == 'b') { for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, @@ -1655,10 +1604,7 @@ DEFUN (vnc_nve_group_export_no_prefixlist, VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1714,10 +1660,7 @@ DEFUN (vnc_nve_group_export_prefixlist, VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); afi_t afi; - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1765,10 +1708,7 @@ DEFUN (vnc_nve_group_export_no_routemap, VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1817,10 +1757,7 @@ DEFUN (vnc_nve_group_export_routemap, VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - if (!bgp->rfapi_cfg) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); /* make sure it's still in list */ if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { @@ -1865,10 +1802,8 @@ DEFUN (vnc_nve_export_no_prefixlist, struct rfapi_cfg *hc; afi_t afi; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (strmatch(argv[4]->text, "ipv4")) { afi = AFI_IP; @@ -1916,10 +1851,8 @@ DEFUN (vnc_nve_export_prefixlist, struct rfapi_cfg *hc; afi_t afi; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (strmatch(argv[3]->text, "ipv4")) { afi = AFI_IP; @@ -1958,10 +1891,8 @@ DEFUN (vnc_nve_export_no_routemap, VTY_DECLVAR_CONTEXT(bgp, bgp); struct rfapi_cfg *hc; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (argv[3]->arg[0] == 'b') { if (((argc > 5) && hc->routemap_export_bgp_name @@ -2001,10 +1932,8 @@ DEFUN (vnc_nve_export_routemap, VTY_DECLVAR_CONTEXT(bgp, bgp); struct rfapi_cfg *hc; - if (!(hc = bgp->rfapi_cfg)) { - vty_out(vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VNC_VTY_CONFIG_CHECK(bgp); + hc = bgp->rfapi_cfg; if (argv[2]->arg[0] == 'b') { if (hc->routemap_export_bgp_name) @@ -2219,6 +2148,8 @@ DEFUN_NOSH (vnc_nve_group, struct listnode *node, *nnode; struct rfapi_rfg_name *rfgn; + VNC_VTY_CONFIG_CHECK(bgp); + /* Search for name */ rfg = bgp_rfapi_cfg_match_byname(bgp, argv[2]->arg, RFAPI_GROUP_CFG_NVE); @@ -2327,8 +2258,7 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ listnode_delete(rfg->nves, rfd); listnode_add(orphaned_nves, rfd); } - list_delete(rfg->nves); - rfg->nves = NULL; + list_delete_and_null(&rfg->nves); } /* delete it */ @@ -2405,7 +2335,7 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ if (vty) vty_out(vty, "\n"); } - list_delete(orphaned_nves); + list_delete_and_null(&orphaned_nves); } } @@ -3385,6 +3315,7 @@ DEFUN_NOSH (vnc_l2_group, { struct rfapi_l2_group_cfg *rfg; VTY_DECLVAR_CONTEXT(bgp, bgp); + VNC_VTY_CONFIG_CHECK(bgp); /* Search for name */ rfg = rfapi_l2_group_lookup_byname(bgp, argv[2]->arg); @@ -3420,7 +3351,7 @@ static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */ if (rfg->rt_export_list) ecommunity_free(&rfg->rt_export_list); if (rfg->labels) - list_delete(rfg->labels); + list_delete_and_null(&rfg->labels); if (rfg->rfp_cfg) XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); listnode_delete(bgp->rfapi_cfg->l2_groups, rfg); @@ -3825,10 +3756,10 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h) bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX); bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL); if (h->l2_groups != NULL) - list_delete(h->l2_groups); - list_delete(h->nve_groups_sequential); - list_delete(h->rfg_export_direct_bgp_l); - list_delete(h->rfg_export_zebra_l); + list_delete_and_null(&h->l2_groups); + list_delete_and_null(&h->nve_groups_sequential); + list_delete_and_null(&h->rfg_export_direct_bgp_l); + list_delete_and_null(&h->rfg_export_zebra_l); if (h->default_rt_export_list) ecommunity_free(&h->default_rt_export_list); if (h->default_rt_import_list) diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 477716cafb..b093265ffb 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -122,7 +122,7 @@ int rfapi_get_response_lifetime_default(void *rfp_start_val) /*------------------------------------------ * rfapi_is_vnc_configured * - * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured + * Returns if VNC is configured * * input: * rfp_start_val value returned by rfp_start or @@ -137,7 +137,9 @@ int rfapi_get_response_lifetime_default(void *rfp_start_val) int rfapi_is_vnc_configured(void *rfp_start_val) { struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); - return bgp_rfapi_is_vnc_configured(bgp); + if (bgp_rfapi_is_vnc_configured(bgp) == 0) + return 0; + return ENXIO; } @@ -490,7 +492,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd, * Delete local_nexthops list */ if (bi->extra && bi->extra->vnc.export.local_nexthops) { - list_delete(bi->extra->vnc.export.local_nexthops); + list_delete_and_null( + &bi->extra->vnc.export.local_nexthops); } bgp_aggregate_decrement(bgp, p, bi, afi, safi); diff --git a/bgpd/rfapi/rfapi.h b/bgpd/rfapi/rfapi.h index 8eb0d717df..6af2ebeeb8 100644 --- a/bgpd/rfapi/rfapi.h +++ b/bgpd/rfapi/rfapi.h @@ -862,7 +862,7 @@ extern int rfapi_get_response_lifetime_default(void *rfp_start_val); /*------------------------------------------ * rfapi_is_vnc_configured * - * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured + * Returns if VNC is configured * * input: * rfp_start_val value returned by rfp_start or diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index d963a759ac..894bdad767 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -3530,7 +3530,10 @@ void rfapiBgpInfoFilteredImportVPN( * Compare types. Doing so prevents a RFP-originated * route from matching an imported route, for example. */ - assert(bi->type == type); + if (VNC_DEBUG(VERBOSE) && bi->type != type) + /* should be handled by RDs, but warn for now */ + zlog_warn("%s: type mismatch! (bi=%d, arg=%d)", + __func__, bi->type, type); vnc_zlog_debug_verbose("%s: found matching bi", __func__); @@ -3861,6 +3864,20 @@ void rfapiBgpInfoFilteredImportVPN( VNC_ITRCCK; } +static void rfapiBgpInfoFilteredImportBadSafi( + struct rfapi_import_table *import_table, int action, struct peer *peer, + void *rfd, /* set for looped back routes */ + struct prefix *p, + struct prefix *aux_prefix, /* AFI_L2VPN: optional IP */ + afi_t afi, struct prefix_rd *prd, + struct attr *attr, /* part of bgp_info */ + u_char type, /* part of bgp_info */ + u_char sub_type, /* part of bgp_info */ + uint32_t *label) /* part of bgp_info */ +{ + vnc_zlog_debug_verbose("%s: Error, bad safi", __func__); +} + static rfapi_bi_filtered_import_f * rfapiBgpInfoFilteredImportFunction(safi_t safi) { @@ -3874,7 +3891,7 @@ rfapiBgpInfoFilteredImportFunction(safi_t safi) default: /* not expected */ zlog_err("%s: bad safi %d", __func__, safi); - return NULL; + return rfapiBgpInfoFilteredImportBadSafi; } } diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index 6a7595443a..47a72d75fd 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -1378,6 +1378,8 @@ struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, #if DEBUG_L2_EXTRA vnc_zlog_debug_verbose("%s: inserted rfd=%p mon_eth=%p, rc=%d", __func__, rfd, val, rc); +#else + (void)rc; #endif /* diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 748c0c476b..92cd1888ee 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -510,13 +510,12 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) */ if (pn->info) { if (pn->info != (void *)1) { - list_delete( - (struct list - *)(pn->info)); + list_delete_and_null( + (struct list **)(&pn->info)); } pn->info = NULL; - route_unlock_node( - pn); /* linklist or 1 deleted */ + /* linklist or 1 deleted */ + route_unlock_node(pn); } } } @@ -1435,7 +1434,7 @@ callback: } delete_list->del = (void (*)(void *))rfapi_info_free; - list_delete(delete_list); + list_delete_and_null(&delete_list); } RFAPI_RIB_CHECK_COUNTS(0, 0); @@ -1450,7 +1449,7 @@ callback: route_unlock_node(pn); } if (lPendCost) { - list_delete(lPendCost); + list_delete_and_null(&lPendCost); pn->info = NULL; route_unlock_node(pn); } @@ -1634,7 +1633,7 @@ void rfapiRibUpdatePendingNode( */ if (pn->info) { if (pn->info != (void *)1) { - list_delete((struct list *)(pn->info)); + list_delete_and_null((struct list **)(&pn->info)); } pn->info = NULL; route_unlock_node(pn); /* linklist or 1 deleted */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index c6958237a3..f678e78825 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -3274,7 +3274,7 @@ static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda, } list_delete_all_node(adb_delete_list); } - list_delete(adb_delete_list); + list_delete_and_null(&adb_delete_list); } @@ -4074,12 +4074,11 @@ DEFUN (clear_vnc_mac_all_prefix, /* copied from rfp_vty.c */ static int check_and_display_is_vnc_running(struct vty *vty) { - if (!bgp_rfapi_is_vnc_configured(NULL)) + if (bgp_rfapi_is_vnc_configured(NULL) == 0) return 1; /* is running */ if (vty) { - vty_out(vty, - "VNC is not configured. (There are no configured BGP VPN SAFI peers.)\n"); + vty_out(vty, "VNC is not configured.\n"); } return 0; /* not running */ } @@ -4089,7 +4088,7 @@ static int rfapi_vty_show_nve_summary(struct vty *vty, { struct bgp *bgp_default = bgp_get_default(); struct rfapi *h; - int is_vnc_running = !bgp_rfapi_is_vnc_configured(bgp_default); + int is_vnc_running = (bgp_rfapi_is_vnc_configured(bgp_default) == 0); int active_local_routes; int active_remote_routes; diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index b699cec9e7..75347a7eea 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -1544,7 +1544,7 @@ void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi) if (nve_list) { vnc_direct_bgp_unexport_table( afi, it->imported_vpn[afi], nve_list); - list_free(nve_list); + list_delete_and_null(&nve_list); } } } diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 117d4fbfd4..4122ae5a9f 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -2426,7 +2426,7 @@ void vnc_import_bgp_exterior_add_route_interior( skiplist_delete(it->monitor_exterior_orphans, bi_exterior, NULL); } - list_delete(list_adopted); + list_delete_and_null(&list_adopted); } } diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 3fc6ddfe35..b8058cf1e5 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -584,7 +584,7 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp, nve_list_to_nh_array(rn->p.family, nves, &nexthop_count, &nh_ary, &nhp_ary); - list_delete(nves); + list_delete_and_null(&nves); if (nexthop_count) vnc_zebra_route_msg(&rn->p, nexthop_count, nhp_ary, @@ -753,7 +753,7 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp, vnc_zlog_debug_verbose("%s: family: %d, nve count: %d", __func__, family, nexthop_count); - list_delete(nves); + list_delete_and_null(&nves); if (nexthop_count) { /* diff --git a/configure.ac b/configure.ac index 2faaa7fc8e..cae5061122 100755 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,23 @@ CC="${CC% -std=c99}" AC_C_FLAG([-std=gnu11], [CC="$ac_cc"], [CC="$CC -std=gnu11"]) +dnl if the user has specified any CFLAGS, override our settings +if test "x${enable_dev_build}" = "xyes"; then + AC_DEFINE(DEV_BUILD,,Build for development) + if test "z$orig_cflags" = "z"; then + AC_C_FLAG([-g3]) + AC_C_FLAG([-O0]) + fi +else + if test "z$orig_cflags" = "z"; then + AC_C_FLAG([-g]) + AC_C_FLAG([-Os], [ + AC_C_FLAG([-O2]) + ]) + fi +fi +AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"]) + dnl always want these CFLAGS AC_C_FLAG([-fno-omit-frame-pointer]) AC_C_FLAG([-funwind-tables]) @@ -428,21 +445,6 @@ fi AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"]) -if test "x${enable_dev_build}" = "xyes"; then - AC_DEFINE(DEV_BUILD,,Build for development) - AC_C_FLAG([-g]) - AC_C_FLAG([-O0]) -else - dnl if the user specified any CFLAGS, we don't add "-g -Os/-O2" here - if test "z$orig_cflags" = "z"; then - AC_C_FLAG([-g]) - AC_C_FLAG([-Os], [ - AC_C_FLAG([-O2]) - ]) - fi -fi -AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"]) - # # Python for clippy # diff --git a/debian/control b/debian/control index d2b2e7cea6..84b04c347d 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ XS-Testsuite: autopkgtest Package: frr Architecture: any -Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute, ${misc:Depends}, libc-ares2 +Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute2 | iproute, ${misc:Depends}, libc-ares2 Pre-Depends: adduser Conflicts: zebra, zebra-pj, quagga Replaces: zebra, zebra-pj diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md index b33fb60253..bdd0a96249 100644 --- a/doc/Building_FRR_on_Ubuntu1604.md +++ b/doc/Building_FRR_on_Ubuntu1604.md @@ -14,7 +14,7 @@ Add packages: apt-get install git autoconf automake libtool make gawk libreadline-dev \ texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ - python-pytest libc-ares-dev python3-dev libsystemd-dev + python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr Get FRR, compile it and install it (from Git) --------------------------------------------- @@ -113,7 +113,7 @@ Add the following lines to `/etc/modules-load.d/modules.conf`: **Reboot** or use `sysctl -p` to apply the same config to the running system -### Install the systemd service +### Install the systemd service (if rebooted from last step, change directory back to frr directory) sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service sudo install -m 644 tools/etc/default/frr /etc/default/frr diff --git a/doc/install.texi b/doc/install.texi index 9a98f46733..1930af95e6 100644 --- a/doc/install.texi +++ b/doc/install.texi @@ -97,6 +97,10 @@ Controls backtrace support for the crash handlers. This is autodetected by default. Using the switch will enforce the requested behaviour, failing with an error if support is requested but not available. On BSD systems, this needs libexecinfo, while on glibc support for this is part of libc itself. +@item --enable-dev-build +Turn on some options for compiling FRR within a development environment in +mind. Specifically turn on -g3 -O0 for compiling options and add inclusion +of grammar sandbox. @end table You may specify any combination of the above options to the configure diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 091b271129..20656ec4eb 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -210,14 +210,14 @@ void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp, struct eigrp_interface *ei) { vty_out(vty, "%-11s ", eigrp_if_name_string(ei)); - vty_out(vty, "%-11u", IF_DEF_PARAMS(ei->ifp)->bandwidth); - vty_out(vty, "%-11u", IF_DEF_PARAMS(ei->ifp)->delay); + vty_out(vty, "%-11u", ei->params.bandwidth); + vty_out(vty, "%-11u", ei->params.delay); vty_out(vty, "%-7u", ei->nbrs->count); vty_out(vty, "%u %c %-10u", 0, '/', eigrp_neighbor_packet_queue_sum(ei)); vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0); - vty_out(vty, "%-8u %-8u \n", IF_DEF_PARAMS(ei->ifp)->v_hello, - IF_DEF_PARAMS(ei->ifp)->v_wait); + vty_out(vty, "%-8u %-8u \n", ei->params.v_hello, + ei->params.v_wait); } void show_ip_eigrp_interface_detail(struct vty *vty, struct eigrp *eigrp, @@ -301,7 +301,7 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) tn->serno); if (successors) - list_delete(successors); + list_delete_and_null(&successors); } void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c index 7b9e0de525..7a8fd027ca 100644 --- a/eigrpd/eigrp_filter.c +++ b/eigrpd/eigrp_filter.c @@ -187,6 +187,7 @@ void eigrp_distribute_update(struct distribute *dist) break; } } + assert(ei != NULL); /* Access-list for interface in */ if (dist->list[DISTRIBUTE_V4_IN]) { @@ -294,10 +295,10 @@ void eigrp_distribute_update_interface(struct interface *ifp) */ void eigrp_distribute_update_all(struct prefix_list *notused) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) eigrp_distribute_update_interface(ifp); } diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index 4514e5b9a8..29357c2b24 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -366,7 +366,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) // neighbors left } - list_delete(successors); + list_delete_and_null(&successors); return 1; } @@ -393,7 +393,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) // neighbors left } - list_delete(successors); + list_delete_and_null(&successors); return 1; } @@ -445,7 +445,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) ne = listnode_head(successors); eigrp_send_reply(ne->adv_router, prefix); - list_delete(successors); + list_delete_and_null(&successors); } prefix->state = EIGRP_FSM_STATE_PASSIVE; @@ -475,7 +475,7 @@ int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) msg); - list_delete(successors); + list_delete_and_null(&successors); return 1; } @@ -500,7 +500,7 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) eigrp_send_reply(ne->adv_router, prefix); - list_delete(successors); + list_delete_and_null(&successors); } prefix->req_action |= EIGRP_FSM_NEED_UPDATE; listnode_add(eigrp->topology_changes_internalIPV4, prefix); @@ -536,7 +536,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) // neighbors left } - list_delete(successors); + list_delete_and_null(&successors); return 1; } @@ -552,6 +552,6 @@ int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2; msg->prefix->distance = ne->distance; - list_delete(successors); + list_delete_and_null(&successors); return 1; } diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index 49647c6b85..1cb265cf12 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -89,7 +89,7 @@ int eigrp_hello_timer(struct thread *thread) if (IS_DEBUG_EIGRP(0, TIMERS)) zlog_debug("Start Hello Timer (%s) Expire [%u]", IF_NAME(ei), - EIGRP_IF_PARAM(ei, v_hello)); + ei->params.v_hello); /* Sending hello packet. */ eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL); @@ -97,7 +97,7 @@ int eigrp_hello_timer(struct thread *thread) /* Hello timer set. */ ei->t_hello = NULL; thread_add_timer(master, eigrp_hello_timer, ei, - EIGRP_IF_PARAM(ei, v_hello), &ei->t_hello); + ei->params.v_hello, &ei->t_hello); return 0; } @@ -600,7 +600,7 @@ static u_int16_t eigrp_hello_parameter_encode(struct eigrp_interface *ei, } // and set hold time value.. - stream_putw(s, IF_DEF_PARAMS(ei->ifp)->v_wait); + stream_putw(s, ei->params.v_wait); return length; } @@ -637,12 +637,12 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei, eigrp_packet_header_init(EIGRP_OPC_HELLO, ei->eigrp, ep->s, 0, 0, ack); // encode Authentication TLV - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); - } else if ((IF_DEF_PARAMS(ei->ifp)->auth_type + } else if ((ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_SHA256_to_stream(ep->s, ei); } @@ -676,13 +676,13 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei, // set soruce address for the hello packet ep->dst.s_addr = addr; - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_BASIC_HELLO_FLAG); - } else if ((IF_DEF_PARAMS(ei->ifp)->auth_type + } else if ((ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + && (ei->params.auth_keychain != NULL)) { eigrp_make_sha256_digest(ei, ep->s, EIGRP_AUTH_BASIC_HELLO_FLAG); } diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index f2512eadad..ec29d86fd2 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -55,41 +55,22 @@ #include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_fsm.h" -static void eigrp_delete_from_if(struct interface *, struct eigrp_interface *); - -static void eigrp_add_to_if(struct interface *ifp, struct eigrp_interface *ei) -{ - struct route_node *rn; - struct prefix p; - - p = *ei->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_get(IF_OIFS(ifp), &p); - /* rn->info should either be NULL or equal to this ei - * as route_node_get may return an existing node - */ - assert(!rn->info || rn->info == ei); - rn->info = ei; -} - struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) { - struct eigrp_interface *ei; + struct eigrp_interface *ei = ifp->info; int i; - if ((ei = eigrp_if_table_lookup(ifp, p)) == NULL) { - ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface)); - memset(ei, 0, sizeof(struct eigrp_interface)); - } else + if (ei) return ei; + ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface)); + /* Set zebra interface pointer. */ ei->ifp = ifp; ei->address = p; - eigrp_add_to_if(ifp, ei); + ifp->info = ei; listnode_add(eigrp->eiflist, ei); ei->type = EIGRP_IFTYPE_BROADCAST; @@ -106,39 +87,32 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, ei->routemap[i] = NULL; } - return ei; -} - -/* lookup ei for specified prefix/ifp */ -struct eigrp_interface *eigrp_if_table_lookup(struct interface *ifp, - struct prefix *prefix) -{ - struct prefix p; - struct route_node *rn; - struct eigrp_interface *rninfo = NULL; - - p = *prefix; - p.prefixlen = IPV4_MAX_PREFIXLEN; + ei->eigrp = eigrp; - /* route_node_get implicitly locks */ - if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) { - rninfo = (struct eigrp_interface *)rn->info; - route_unlock_node(rn); - } + ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; + ei->params.v_wait = EIGRP_HOLD_INTERVAL_DEFAULT; + ei->params.bandwidth = EIGRP_BANDWIDTH_DEFAULT; + ei->params.delay = EIGRP_DELAY_DEFAULT; + ei->params.reliability = EIGRP_RELIABILITY_DEFAULT; + ei->params.load = EIGRP_LOAD_DEFAULT; + ei->params.auth_type = EIGRP_AUTH_TYPE_NONE; + ei->params.auth_keychain = NULL; - return rninfo; + return ei; } int eigrp_if_delete_hook(struct interface *ifp) { - struct route_node *rn; + struct eigrp_interface *ei = ifp->info; + struct eigrp *eigrp; - route_table_finish(IF_OIFS(ifp)); + if (!ei) + return 0; + + list_delete_and_null(&ei->nbrs); - for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) - if (rn->info) - eigrp_del_if_params(rn->info); - route_table_finish(IF_OIFS_PARAMS(ifp)); + eigrp = ei->eigrp; + listnode_delete(eigrp->eiflist, ei); XFREE(MTYPE_EIGRP_IF_INFO, ifp->info); ifp->info = NULL; @@ -151,95 +125,16 @@ struct list *eigrp_iflist; void eigrp_if_init() { /* Initialize Zebra interface data structure. */ - hook_register_prio(if_add, 0, eigrp_if_new_hook); + //hook_register_prio(if_add, 0, eigrp_if_new); hook_register_prio(if_del, 0, eigrp_if_delete_hook); } -int eigrp_if_new_hook(struct interface *ifp) -{ - int rc = 0; - - ifp->info = XCALLOC(MTYPE_EIGRP_IF_INFO, sizeof(struct eigrp_if_info)); - - IF_OIFS(ifp) = route_table_init(); - IF_OIFS_PARAMS(ifp) = route_table_init(); - - IF_DEF_PARAMS(ifp) = eigrp_new_if_params(); - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello); - IF_DEF_PARAMS(ifp)->v_hello = (u_int32_t)EIGRP_HELLO_INTERVAL_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait); - IF_DEF_PARAMS(ifp)->v_wait = (u_int16_t)EIGRP_HOLD_INTERVAL_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), bandwidth); - IF_DEF_PARAMS(ifp)->bandwidth = (u_int32_t)EIGRP_BANDWIDTH_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), delay); - IF_DEF_PARAMS(ifp)->delay = (u_int32_t)EIGRP_DELAY_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), reliability); - IF_DEF_PARAMS(ifp)->reliability = (u_char)EIGRP_RELIABILITY_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), load); - IF_DEF_PARAMS(ifp)->load = (u_char)EIGRP_LOAD_DEFAULT; - SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type); - IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_NONE; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_keychain); - IF_DEF_PARAMS(ifp)->auth_keychain = NULL; - - return rc; -} - -struct eigrp_if_params *eigrp_new_if_params(void) -{ - struct eigrp_if_params *eip; - - eip = XCALLOC(MTYPE_EIGRP_IF_PARAMS, sizeof(struct eigrp_if_params)); - if (!eip) - return NULL; - - UNSET_IF_PARAM(eip, passive_interface); - UNSET_IF_PARAM(eip, v_hello); - UNSET_IF_PARAM(eip, v_wait); - UNSET_IF_PARAM(eip, bandwidth); - UNSET_IF_PARAM(eip, delay); - UNSET_IF_PARAM(eip, reliability); - UNSET_IF_PARAM(eip, load); - UNSET_IF_PARAM(eip, auth_keychain); - UNSET_IF_PARAM(eip, auth_type); - - return eip; -} void eigrp_del_if_params(struct eigrp_if_params *eip) { if (eip->auth_keychain) free(eip->auth_keychain); - - XFREE(MTYPE_EIGRP_IF_PARAMS, eip); -} - -struct eigrp_if_params *eigrp_lookup_if_params(struct interface *ifp, - struct in_addr addr) -{ - struct prefix p; - struct route_node *rn; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.u.prefix4 = addr; - - rn = route_node_lookup(IF_OIFS_PARAMS(ifp), &p); - - if (rn) { - route_unlock_node(rn); - return rn->info; - } - - return NULL; } int eigrp_if_up(struct eigrp_interface *ei) @@ -266,10 +161,10 @@ int eigrp_if_up(struct eigrp_interface *ei) /*Prepare metrics*/ metric.bandwidth = - eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(ei, bandwidth)); - metric.delay = eigrp_delay_to_scaled(EIGRP_IF_PARAM(ei, delay)); - metric.load = EIGRP_IF_PARAM(ei, load); - metric.reliability = EIGRP_IF_PARAM(ei, reliability); + eigrp_bandwidth_to_scaled(ei->params.bandwidth); + metric.delay = eigrp_delay_to_scaled(ei->params.delay); + metric.load = ei->params.load; + metric.reliability = ei->params.reliability; metric.mtu[0] = 0xDC; metric.mtu[1] = 0x05; metric.mtu[2] = 0x00; @@ -387,33 +282,43 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei) } } +bool eigrp_if_is_passive(struct eigrp_interface *ei) +{ + if (ei->params.passive_interface == EIGRP_IF_ACTIVE) + return false; + + if (ei->eigrp->passive_interface_default == EIGRP_IF_ACTIVE) + return false; + + return true; +} + void eigrp_if_set_multicast(struct eigrp_interface *ei) { - if ((EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_ACTIVE)) { + if (!eigrp_if_is_passive(ei)) { /* The interface should belong to the EIGRP-all-routers group. */ - if (!EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS) + if (!ei->member_allrouters && (eigrp_if_add_allspfrouters(ei->eigrp, ei->address, ei->ifp->ifindex) >= 0)) /* Set the flag only if the system call to join * succeeded. */ - EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS); + ei->member_allrouters = true; } else { /* The interface should NOT belong to the EIGRP-all-routers * group. */ - if (EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS)) { + if (ei->member_allrouters) { /* Only actually drop if this is the last reference */ - if (EI_MEMBER_COUNT(ei, MEMBER_ALLROUTERS) == 1) - eigrp_if_drop_allspfrouters(ei->eigrp, - ei->address, - ei->ifp->ifindex); + eigrp_if_drop_allspfrouters(ei->eigrp, + ei->address, + ei->ifp->ifindex); /* Unset the flag regardless of whether the system call to leave the group succeeded, since it's much safer to assume that we are not a member. */ - EI_MEMBER_LEFT(ei, MEMBER_ALLROUTERS); + ei->member_allrouters = false; } } } @@ -428,7 +333,8 @@ u_char eigrp_default_iftype(struct interface *ifp) return EIGRP_IFTYPE_BROADCAST; } -void eigrp_if_free(struct eigrp_interface *ei, int source) +void eigrp_if_free(struct eigrp_interface *ei, + int source) { struct prefix dest_addr; struct eigrp_prefix_entry *pe; @@ -448,48 +354,21 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_if_down(ei); - list_delete(ei->nbrs); - eigrp_delete_from_if(ei->ifp, ei); + list_delete_and_null(&ei->nbrs); listnode_delete(ei->eigrp->eiflist, ei); - - thread_cancel_event(master, ei); - - memset(ei, 0, sizeof(*ei)); - XFREE(MTYPE_EIGRP_IF, ei); -} - -static void eigrp_delete_from_if(struct interface *ifp, - struct eigrp_interface *ei) -{ - struct route_node *rn; - struct prefix p; - - p = *ei->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_lookup(IF_OIFS(ei->ifp), &p); - assert(rn); - assert(rn->info); - rn->info = NULL; - route_unlock_node(rn); - route_unlock_node(rn); } /* Simulate down/up on the interface. This is needed, for example, when the MTU changes. */ void eigrp_if_reset(struct interface *ifp) { - struct route_node *rn; + struct eigrp_interface *ei = ifp->info; - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { - struct eigrp_interface *ei; + if (!ei) + return; - if ((ei = rn->info) == NULL) - continue; - - eigrp_if_down(ei); - eigrp_if_up(ei); - } + eigrp_if_down(ei); + eigrp_if_up(ei); } struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp, @@ -538,41 +417,6 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, return NULL; } -/* determine receiving interface by ifp and source address */ -struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *eigrp, - struct in_addr src, - struct interface *ifp) -{ - struct route_node *rn; - struct prefix addr; - struct eigrp_interface *ei, *match; - - addr.family = AF_INET; - addr.u.prefix4 = src; - addr.prefixlen = IPV4_MAX_BITLEN; - - match = NULL; - - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { - ei = rn->info; - - if (!ei) /* oi can be NULL for PtP aliases */ - continue; - - if (if_is_loopback(ei->ifp)) - continue; - - if (prefix_match(CONNECTED_PREFIX(ei->connected), - &addr)) { - if ((match == NULL) || (match->address->prefixlen - < ei->address->prefixlen)) - match = ei; - } - } - - return match; -} - u_int32_t eigrp_bandwidth_to_scaled(u_int32_t bandwidth) { uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth; diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h index df5c7d395e..0999c938f6 100644 --- a/eigrpd/eigrp_interface.h +++ b/eigrpd/eigrp_interface.h @@ -37,14 +37,10 @@ extern void eigrp_if_init(void); extern int eigrp_if_new_hook(struct interface *); extern int eigrp_if_delete_hook(struct interface *); +extern bool eigrp_if_is_passive(struct eigrp_interface *ei); extern void eigrp_del_if_params(struct eigrp_if_params *); -extern struct eigrp_if_params *eigrp_new_if_params(void); extern struct eigrp_interface *eigrp_if_new(struct eigrp *, struct interface *, struct prefix *); -extern struct eigrp_interface *eigrp_if_table_lookup(struct interface *, - struct prefix *); -extern struct eigrp_if_params *eigrp_lookup_if_params(struct interface *, - struct in_addr); extern int eigrp_if_up(struct eigrp_interface *); extern void eigrp_if_stream_set(struct eigrp_interface *); extern void eigrp_if_set_multicast(struct eigrp_interface *); @@ -58,8 +54,6 @@ extern struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *, struct in_addr); extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *, const char *); -struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *, struct in_addr, - struct interface *); /* Simulate down/up on the interface. */ extern void eigrp_if_reset(struct interface *); diff --git a/eigrpd/eigrp_macros.h b/eigrpd/eigrp_macros.h index fdb84673df..14a8892bac 100644 --- a/eigrpd/eigrp_macros.h +++ b/eigrpd/eigrp_macros.h @@ -28,54 +28,14 @@ #ifndef _ZEBRA_EIGRP_MACROS_H_ #define _ZEBRA_EIGRP_MACROS_H_ -#define DECLARE_IF_PARAM(T, P) T P; u_char P##__config:1 -#define IF_EIGRP_IF_INFO(I) ((struct eigrp_if_info *)((I)->info)) -#define IF_OIFS(I) (IF_EIGRP_IF_INFO (I)->eifs) -#define IF_OIFS_PARAMS(I) (IF_EIGRP_IF_INFO (I)->params) -#define SET_IF_PARAM(S, P) ((S)->P##__config) = 1 -#define IF_DEF_PARAMS(I) (IF_EIGRP_IF_INFO (I)->def_params) - -#define UNSET_IF_PARAM(S, P) ((S)->P##__config) = 0 - -#define EIGRP_IF_PARAM_CONFIGURED(S, P) ((S) && (S)->P##__config) -#define EIGRP_IF_PARAM(O, P) \ - (EIGRP_IF_PARAM_CONFIGURED((O)->params, P) \ - ? (O)->params->P \ - : IF_DEF_PARAMS((O)->ifp)->P) - -#define EIGRP_IF_PASSIVE_STATUS(O) \ - (EIGRP_IF_PARAM_CONFIGURED((O)->params, passive_interface) \ - ? (O)->params->passive_interface \ - : (EIGRP_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp), \ - passive_interface) \ - ? IF_DEF_PARAMS((O)->ifp)->passive_interface \ - : (O)->eigrp->passive_interface_default)) - -//------------------------------------------------------------------------------------------------------------------------------------ +//-------------------------------------------------------------------------- #define EIGRP_IF_STRING_MAXLEN 40 #define IF_NAME(I) eigrp_if_name_string ((I)) -//------------------------------------------------------------------------------------------------------------------------------------ - -/*Macros for EIGRP interface multicast membership*/ -#define EI_MEMBER_FLAG(M) (1 << (M)) -#define EI_MEMBER_COUNT(O,M) (IF_EIGRP_IF_INFO(ei->ifp)->membership_counts[(M)]) -#define EI_MEMBER_CHECK(O, M) \ - (CHECK_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M))) -#define EI_MEMBER_JOINED(O, M) \ - do { \ - SET_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M)); \ - IF_EIGRP_IF_INFO((O)->ifp)->membership_counts[(M)]++; \ - } while (0) -#define EI_MEMBER_LEFT(O, M) \ - do { \ - UNSET_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M)); \ - IF_EIGRP_IF_INFO((O)->ifp)->membership_counts[(M)]--; \ - } while (0) +//-------------------------------------------------------------------------- -//----------------------------------------------------------------------------------------------------------------------------------- /* Topology Macros */ diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index c5f4080317..56327f1205 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -231,9 +231,9 @@ int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct route_node *rn; struct interface *ifp; - struct listnode *node; rn = route_node_get(eigrp->networks, (struct prefix *)p); if (rn->info) { @@ -251,7 +251,7 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) eigrp_router_id_update(eigrp); /* Run network config now. */ /* Get target interface. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { zlog_debug("Setting up %s", ifp->name); eigrp_network_run_interface(eigrp, p, ifp); } @@ -271,6 +271,7 @@ static int eigrp_network_match_iface(const struct connected *co, static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p, struct interface *ifp) { + struct eigrp_interface *ei; struct listnode *cnode; struct connected *co; @@ -282,24 +283,15 @@ static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p, continue; if (p->family == co->address->family - && !eigrp_if_table_lookup(ifp, co->address) + && !ifp->info && eigrp_network_match_iface(co, p)) { - struct eigrp_interface *ei; ei = eigrp_if_new(eigrp, ifp, co->address); ei->connected = co; - ei->params = eigrp_lookup_if_params( - ifp, ei->address->u.prefix4); - /* Relate eigrp interface to eigrp instance. */ ei->eigrp = eigrp; - /* update network type as interface flag */ - /* If network type is specified previously, - skip network type setting. */ - ei->type = IF_DEF_PARAMS(ifp)->type; - /* if router_id is not configured, dont bring up * interfaces. * eigrp_router_id_update() will call eigrp_if_update @@ -415,16 +407,17 @@ u_int32_t eigrp_calculate_metrics(struct eigrp *eigrp, u_int32_t eigrp_calculate_total_metrics(struct eigrp *eigrp, struct eigrp_nexthop_entry *entry) { + struct eigrp_interface *ei = entry->ei; + entry->total_metric = entry->reported_metric; uint64_t temp_delay = (uint64_t)entry->total_metric.delay - + (uint64_t)eigrp_delay_to_scaled( - EIGRP_IF_PARAM(entry->ei, delay)); + + (uint64_t)eigrp_delay_to_scaled(ei->params.delay); entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC : (u_int32_t)temp_delay; u_int32_t bw = - eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(entry->ei, bandwidth)); + eigrp_bandwidth_to_scaled(ei->params.bandwidth); entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw ? bw : entry->total_metric.bandwidth; diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index d2bff74a54..83ff194729 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -108,7 +108,7 @@ int eigrp_make_md5_digest(struct eigrp_interface *ei, struct stream *s, stream_get(auth_TLV, s, EIGRP_AUTH_MD5_TLV_SIZE); stream_set_getp(s, backup_get); - keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain); + keychain = keychain_lookup(ei->params.auth_keychain); if (keychain) key = key_lookup_for_send(keychain); else { @@ -169,7 +169,7 @@ int eigrp_check_md5_digest(struct stream *s, struct TLV_MD5_Authentication_Type *auth_TLV; struct eigrp_header *eigrph; - if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(authTLV->key_sequence)) { + if (ntohl(nbr->crypt_seqnum) > ntohl(authTLV->key_sequence)) { zlog_warn( "interface %s: eigrp_check_md5 bad sequence %d (expect %d)", IF_NAME(nbr->ei), ntohl(authTLV->key_sequence), @@ -189,7 +189,7 @@ int eigrp_check_md5_digest(struct stream *s, ibuf = s->data; backup_end = s->endp; - keychain = keychain_lookup(IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain); + keychain = keychain_lookup(nbr->ei->params.auth_keychain); if (keychain) key = key_lookup_for_send(keychain); @@ -265,7 +265,7 @@ int eigrp_make_sha256_digest(struct eigrp_interface *ei, struct stream *s, stream_get(auth_TLV, s, EIGRP_AUTH_SHA256_TLV_SIZE); stream_set_getp(s, backup_get); - keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain); + keychain = keychain_lookup(ei->params.auth_keychain); if (keychain) key = key_lookup_for_send(keychain); @@ -317,7 +317,6 @@ int eigrp_write(struct thread *thread) struct ip iph; struct msghdr msg; struct iovec iov[2]; - u_int16_t opcode = 0; u_int32_t seqno, ack; int ret; @@ -363,7 +362,6 @@ int eigrp_write(struct thread *thread) * this outgoing packet. */ eigrph = (struct eigrp_header *)STREAM_DATA(ep->s); - opcode = eigrph->opcode; seqno = ntohl(eigrph->sequence); ack = ntohl(eigrph->ack); if (ep->nbr && (ack != ep->nbr->recv_sequence_number)) { @@ -427,9 +425,8 @@ int eigrp_write(struct thread *thread) if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND)) { eigrph = (struct eigrp_header *)STREAM_DATA(ep->s); - opcode = eigrph->opcode; zlog_debug("Sending [%s][%d/%d] to [%s] via [%s] ret [%d].", - lookup_msg(eigrp_packet_type_str, opcode, NULL), + lookup_msg(eigrp_packet_type_str, eigrph->opcode, NULL), seqno, ack, inet_ntoa(ep->dst), IF_NAME(ei), ret); } @@ -522,7 +519,7 @@ int eigrp_read(struct thread *thread) } /* associate packet with eigrp interface */ - ei = eigrp_if_lookup_recv_if(eigrp, iph->ip_src, ifp); + ei = ifp->info; /* eigrp_verify_header() relies on a valid "ei" and thus can be called only @@ -557,21 +554,8 @@ int eigrp_read(struct thread *thread) // stream_get_getp(ibuf))) // return -1; - /* Now it is safe to access all fields of EIGRP packet header. */ - /* associate packet with eigrp interface */ - ei = eigrp_if_lookup_recv_if(eigrp, iph->ip_src, ifp); - - /* eigrp_verify_header() relies on a valid "ei" and thus can be called - only - after the checks below are passed. These checks in turn access the - fields of unverified "eigrph" structure for their own purposes and - must remain very accurate in doing this. - */ - if (!ei) - return 0; - /* If incoming interface is passive one, ignore it. */ - if (ei && EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_PASSIVE) { + if (ei && eigrp_if_is_passive(ei)) { char buf[3][INET_ADDRSTRLEN]; if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) @@ -586,11 +570,6 @@ int eigrp_read(struct thread *thread) buf[2], sizeof(buf[2]))); if (iph->ip_dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS)) { - /* Try to fix multicast membership. - * Some OS:es may have problems in this area, - * make sure it is removed. - */ - EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS); eigrp_if_set_multicast(ei); } return 0; @@ -1240,12 +1219,12 @@ u_int16_t eigrp_add_authTLV_MD5_to_stream(struct stream *s, authTLV->key_sequence = 0; memset(authTLV->Nullpad, 0, sizeof(authTLV->Nullpad)); - keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain); + keychain = keychain_lookup(ei->params.auth_keychain); if (keychain) key = key_lookup_for_send(keychain); else { - free(IF_DEF_PARAMS(ei->ifp)->auth_keychain); - IF_DEF_PARAMS(ei->ifp)->auth_keychain = NULL; + free(ei->params.auth_keychain); + ei->params.auth_keychain = NULL; eigrp_authTLV_MD5_free(authTLV); return 0; } @@ -1280,12 +1259,12 @@ u_int16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *s, authTLV->key_sequence = 0; memset(authTLV->Nullpad, 0, sizeof(authTLV->Nullpad)); - keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain); + keychain = keychain_lookup(ei->params.auth_keychain); if (keychain) key = key_lookup_for_send(keychain); else { - free(IF_DEF_PARAMS(ei->ifp)->auth_keychain); - IF_DEF_PARAMS(ei->ifp)->auth_keychain = NULL; + free(ei->params.auth_keychain); + ei->params.auth_keychain = NULL; eigrp_authTLV_SHA256_free(authTLV); return 0; } diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 03c3705ffd..88a592e6c9 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -175,8 +175,8 @@ void eigrp_send_query(struct eigrp_interface *ei) ei->eigrp->sequence_number, 0); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); } @@ -199,8 +199,8 @@ void eigrp_send_query(struct eigrp_interface *ei) return; } - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && ei->params.auth_keychain != NULL) { eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 20d8b1b47c..8dbd1a5b35 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -1,5 +1,5 @@ /* - * EIGRP Sending and Receiving EIGRP Reply Packets. + * Eigrp Sending and Receiving EIGRP Reply Packets. * Copyright (C) 2013-2016 * Authors: * Donnie Savage @@ -94,16 +94,16 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe) eigrp->sequence_number, 0); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if (ei->params.auth_type == EIGRP_AUTH_TYPE_MD5 + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); } length += eigrp_add_internalTLV_to_stream(ep->s, pe2); - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index b242bcaae9..70df29c1f1 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -126,15 +126,15 @@ void eigrp_send_siaquery(struct eigrp_neighbor *nbr, nbr->ei->eigrp->sequence_number, 0); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { + if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (nbr->ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei); } length += eigrp_add_internalTLV_to_stream(ep->s, pe); - if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { + if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (nbr->ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index 4998a2d54b..b71e80cfcb 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -125,15 +125,15 @@ void eigrp_send_siareply(struct eigrp_neighbor *nbr, nbr->ei->eigrp->sequence_number, 0); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { + if (nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5 + && nbr->ei->params.auth_keychain != NULL) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei); } length += eigrp_add_internalTLV_to_stream(ep->s, pe); - if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { + if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (nbr->ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 5bc63a7c47..4441f5d004 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -135,10 +135,32 @@ struct eigrp { QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(eigrp) -//------------------------------------------------------------------------------------------------------------------------------------------ + +struct eigrp_if_params { + u_char passive_interface; + u_int32_t v_hello; + u_int16_t v_wait; + u_char type; /* type of interface */ + u_int32_t bandwidth; + u_int32_t delay; + u_char reliability; + u_char load; + + char *auth_keychain; /* Associated keychain with interface*/ + int auth_type; /* EIGRP authentication type */ +}; + +enum { MEMBER_ALLROUTERS = 0, + MEMBER_MAX, +}; /*EIGRP interface structure*/ struct eigrp_interface { + struct eigrp_if_params params; + + /*multicast group refcnts */ + bool member_allrouters; + /* This interface's parent eigrp instance. */ struct eigrp *eigrp; @@ -150,8 +172,6 @@ struct eigrp_interface { /* To which multicast groups do we currently belong? */ - /* Configured varables. */ - struct eigrp_if_params *params; u_char multicast_memberships; @@ -196,39 +216,6 @@ struct eigrp_interface { struct route_map *routemap[EIGRP_FILTER_MAX]; }; -struct eigrp_if_params { - DECLARE_IF_PARAM(u_char, passive_interface); /* EIGRP Interface is - passive: no sending or - receiving (no need to - join multicast groups) - */ - DECLARE_IF_PARAM(u_int32_t, v_hello); /* Hello Interval */ - DECLARE_IF_PARAM(u_int16_t, v_wait); /* Router Hold Time Interval */ - DECLARE_IF_PARAM(u_char, type); /* type of interface */ - DECLARE_IF_PARAM(u_int32_t, bandwidth); - DECLARE_IF_PARAM(u_int32_t, delay); - DECLARE_IF_PARAM(u_char, reliability); - DECLARE_IF_PARAM(u_char, load); - - DECLARE_IF_PARAM(char *, - auth_keychain); /* Associated keychain with interface*/ - DECLARE_IF_PARAM(int, auth_type); /* EIGRP authentication type */ -}; - -enum { MEMBER_ALLROUTERS = 0, - MEMBER_MAX, -}; - -struct eigrp_if_info { - struct eigrp_if_params *def_params; - struct route_table *params; - struct route_table *eifs; - unsigned int - membership_counts[MEMBER_MAX]; /* multicast group refcnts */ -}; - -//------------------------------------------------------------------------------------------------------------------------------------------ - /* Determines if it is first or last packet * when packet consists of multiple packet * chunks because of many route TLV diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index f1bc83af63..94775622d9 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -101,8 +101,7 @@ static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *node1, static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *node) { - list_delete_all_node(node->entries); - list_free(node->entries); + list_delete_and_null(&node->entries); } /* @@ -158,7 +157,7 @@ struct eigrp_nexthop_entry *eigrp_nexthop_entry_new() */ void eigrp_topology_free(struct list *list) { - list_free(list); + list_delete_and_null(&list); } /* @@ -199,7 +198,7 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node, eigrp_zebra_route_add(node->destination, l); } - list_delete(l); + list_delete_and_null(&l); } /* @@ -217,9 +216,8 @@ void eigrp_prefix_entry_delete(struct list *topology, listnode_delete(eigrp->topology_changes_internalIPV4, node); if (listnode_lookup(topology, node) != NULL) { - list_delete_all_node(node->entries); - list_free(node->entries); - list_free(node->rij); + list_delete_and_null(&node->entries); + list_delete_and_null(&node->rij); listnode_delete(topology, node); eigrp_zebra_route_delete(node->destination); XFREE(MTYPE_EIGRP_PREFIX_ENTRY, node); @@ -296,7 +294,7 @@ struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node) * If we have no successors return NULL */ if (!successors->count) { - list_delete(successors); + list_delete_and_null(&successors); successors = NULL; } @@ -475,7 +473,7 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; - list_delete(successors); + list_delete_and_null(&successors); } else { eigrp_zebra_route_delete(prefix->destination); for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry)) diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index baa1ac5533..4a86b48944 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -411,7 +411,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, eigrp_update_send_all(eigrp, ei); if (nbr_prefixes) - list_delete(nbr_prefixes); + list_delete_and_null(&nbr_prefixes); } /*send EIGRP Update packet*/ @@ -434,8 +434,8 @@ void eigrp_update_send_init(struct eigrp_neighbor *nbr) nbr->recv_sequence_number); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { + if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (nbr->ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei); eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_INIT_FLAG); @@ -467,8 +467,8 @@ static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr, u_int32_t seq_no, int length) { - if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && - (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL)) { + if((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && + (nbr->ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG); } @@ -544,8 +544,8 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) seq_no, nbr->recv_sequence_number); // encode Authentication TLV, if needed - if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && - (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) { + if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && + (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei); } @@ -564,8 +564,8 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) ep->s, EIGRP_EOT_FLAG, seq_no, nbr->recv_sequence_number); - if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && - (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) + if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && + (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei); } @@ -610,8 +610,8 @@ void eigrp_update_send(struct eigrp_interface *ei) ep->s, 0, seq_no, 0); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); } @@ -628,8 +628,8 @@ void eigrp_update_send(struct eigrp_interface *ei) continue; if ((length + 0x001D) > (u_int16_t)ei->ifp->mtu) { - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } @@ -646,8 +646,8 @@ void eigrp_update_send(struct eigrp_interface *ei) ep = eigrp_packet_new(ei->ifp->mtu, NULL); eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s, 0, seq_no, 0); - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); } has_tlv = 0; @@ -672,8 +672,8 @@ void eigrp_update_send(struct eigrp_interface *ei) return; } - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } @@ -790,8 +790,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) nbr->recv_sequence_number); // encode Authentication TLV, if needed - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); } @@ -856,8 +856,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) } /* compute Auth digest */ - if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) - && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) { + if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) + && (ei->params.auth_keychain != NULL)) { eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); } diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 01407a746f..d93abbb8b7 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -95,36 +95,32 @@ static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp) for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { vty_frame(vty, "interface %s\n", ei->ifp->name); - if ((IF_DEF_PARAMS(ei->ifp)->auth_type) - == EIGRP_AUTH_TYPE_MD5) { + if (ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) { vty_out(vty, " ip authentication mode eigrp %d md5\n", eigrp->AS); } - if ((IF_DEF_PARAMS(ei->ifp)->auth_type) - == EIGRP_AUTH_TYPE_SHA256) { + if (ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256) { vty_out(vty, " ip authentication mode eigrp %d hmac-sha-256\n", eigrp->AS); } - if (IF_DEF_PARAMS(ei->ifp)->auth_keychain) { + if (ei->params.auth_keychain) { vty_out(vty, " ip authentication key-chain eigrp %d %s\n", eigrp->AS, - IF_DEF_PARAMS(ei->ifp)->auth_keychain); + ei->params.auth_keychain); } - if ((IF_DEF_PARAMS(ei->ifp)->v_hello) - != EIGRP_HELLO_INTERVAL_DEFAULT) { + if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) { vty_out(vty, " ip hello-interval eigrp %d\n", - IF_DEF_PARAMS(ei->ifp)->v_hello); + ei->params.v_hello); } - if ((IF_DEF_PARAMS(ei->ifp)->v_wait) - != EIGRP_HOLD_INTERVAL_DEFAULT) { + if (ei->params.v_wait != EIGRP_HOLD_INTERVAL_DEFAULT) { vty_out(vty, " ip hold-time eigrp %d\n", - IF_DEF_PARAMS(ei->ifp)->v_wait); + ei->params.v_wait); } /*Separate this EIGRP interface configuration from the others*/ @@ -136,26 +132,31 @@ static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp) static int eigrp_write_interface(struct vty *vty) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; + struct eigrp_interface *ei; + + FOR_ALL_INTERFACES (vrf, ifp) { + ei = ifp->info; + if (!ei) + continue; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { vty_frame(vty, "interface %s\n", ifp->name); if (ifp->desc) vty_out(vty, " description %s\n", ifp->desc); - if (IF_DEF_PARAMS(ifp)->bandwidth != EIGRP_BANDWIDTH_DEFAULT) + if (ei->params.bandwidth != EIGRP_BANDWIDTH_DEFAULT) vty_out(vty, " bandwidth %u\n", - IF_DEF_PARAMS(ifp)->bandwidth); - if (IF_DEF_PARAMS(ifp)->delay != EIGRP_DELAY_DEFAULT) - vty_out(vty, " delay %u\n", IF_DEF_PARAMS(ifp)->delay); - if (IF_DEF_PARAMS(ifp)->v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) + ei->params.bandwidth); + if (ei->params.delay != EIGRP_DELAY_DEFAULT) + vty_out(vty, " delay %u\n", ei->params.delay); + if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) vty_out(vty, " ip hello-interval eigrp %u\n", - IF_DEF_PARAMS(ifp)->v_hello); - if (IF_DEF_PARAMS(ifp)->v_wait != EIGRP_HOLD_INTERVAL_DEFAULT) + ei->params.v_hello); + if (ei->params.v_wait != EIGRP_HOLD_INTERVAL_DEFAULT) vty_out(vty, " ip hold-time eigrp %u\n", - IF_DEF_PARAMS(ifp)->v_wait); + ei->params.v_wait); vty_endframe(vty, "!\n"); } @@ -291,8 +292,10 @@ DEFUN (eigrp_passive_interface, char *ifname = argv[1]->arg; for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { - if (strcmp(ifname, ei->ifp->name) == 0) - SET_IF_PARAM(IF_DEF_PARAMS(ei->ifp), passive_interface); + if (strcmp(ifname, ei->ifp->name) == 0) { + ei->params.passive_interface = EIGRP_IF_PASSIVE; + return CMD_SUCCESS; + } } return CMD_SUCCESS; } @@ -310,9 +313,10 @@ DEFUN (no_eigrp_passive_interface, char *ifname = argv[2]->arg; for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { - if (strcmp(ifname, ei->ifp->name) == 0) - UNSET_IF_PARAM(IF_DEF_PARAMS(ei->ifp), - passive_interface); + if (strcmp(ifname, ei->ifp->name) == 0) { + ei->params.passive_interface = EIGRP_IF_ACTIVE; + return CMD_SUCCESS; + } } return CMD_SUCCESS; @@ -599,6 +603,7 @@ DEFUN (eigrp_if_delay, "Throughput delay (tens of microseconds)\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; u_int32_t delay; @@ -609,9 +614,13 @@ DEFUN (eigrp_if_delay, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } delay = atoi(argv[1]->arg); - IF_DEF_PARAMS(ifp)->delay = delay; + ei->params.delay = delay; eigrp_if_reset(ifp); return CMD_SUCCESS; @@ -625,6 +634,7 @@ DEFUN (no_eigrp_if_delay, "Throughput delay (tens of microseconds)\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; eigrp = eigrp_lookup(); @@ -633,8 +643,12 @@ DEFUN (no_eigrp_if_delay, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } - IF_DEF_PARAMS(ifp)->delay = EIGRP_DELAY_DEFAULT; + ei->params.delay = EIGRP_DELAY_DEFAULT; eigrp_if_reset(ifp); return CMD_SUCCESS; @@ -648,6 +662,7 @@ DEFUN (eigrp_if_bandwidth, "Bandwidth in kilobits\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; u_int32_t bandwidth; struct eigrp *eigrp; @@ -657,9 +672,14 @@ DEFUN (eigrp_if_bandwidth, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + bandwidth = atoi(argv[1]->arg); - IF_DEF_PARAMS(ifp)->bandwidth = bandwidth; + ei->params.bandwidth = bandwidth; eigrp_if_reset(ifp); return CMD_SUCCESS; @@ -674,6 +694,7 @@ DEFUN (no_eigrp_if_bandwidth, "Bandwidth in kilobits\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; eigrp = eigrp_lookup(); @@ -682,7 +703,12 @@ DEFUN (no_eigrp_if_bandwidth, return CMD_SUCCESS; } - IF_DEF_PARAMS(ifp)->bandwidth = EIGRP_BANDWIDTH_DEFAULT; + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + + ei->params.bandwidth = EIGRP_BANDWIDTH_DEFAULT; eigrp_if_reset(ifp); return CMD_SUCCESS; @@ -697,6 +723,7 @@ DEFUN (eigrp_if_ip_hellointerval, "Seconds between hello transmissions\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; u_int32_t hello; struct eigrp *eigrp; @@ -706,9 +733,14 @@ DEFUN (eigrp_if_ip_hellointerval, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + hello = atoi(argv[3]->arg); - IF_DEF_PARAMS(ifp)->v_hello = hello; + ei->params.v_hello = hello; return CMD_SUCCESS; } @@ -723,9 +755,8 @@ DEFUN (no_eigrp_if_ip_hellointerval, "Seconds between hello transmissions\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; - struct eigrp_interface *ei; - struct listnode *node, *nnode; eigrp = eigrp_lookup(); if (eigrp == NULL) { @@ -733,17 +764,17 @@ DEFUN (no_eigrp_if_ip_hellointerval, return CMD_SUCCESS; } - IF_DEF_PARAMS(ifp)->v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; - - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { - if (ei->ifp == ifp) { - THREAD_TIMER_OFF(ei->t_hello); - thread_add_timer(master, eigrp_hello_timer, ei, 1, - &ei->t_hello); - break; - } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; } + ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; + + THREAD_TIMER_OFF(ei->t_hello); + thread_add_timer(master, eigrp_hello_timer, ei, 1, + &ei->t_hello); + return CMD_SUCCESS; } @@ -756,6 +787,7 @@ DEFUN (eigrp_if_ip_holdinterval, "Seconds before neighbor is considered down\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; u_int32_t hold; struct eigrp *eigrp; @@ -765,9 +797,14 @@ DEFUN (eigrp_if_ip_holdinterval, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + hold = atoi(argv[3]->arg); - IF_DEF_PARAMS(ifp)->v_wait = hold; + ei->params.v_wait = hold; return CMD_SUCCESS; } @@ -835,6 +872,7 @@ DEFUN (no_eigrp_if_ip_holdinterval, "Seconds before neighbor is considered down\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; eigrp = eigrp_lookup(); @@ -843,22 +881,27 @@ DEFUN (no_eigrp_if_ip_holdinterval, return CMD_SUCCESS; } - IF_DEF_PARAMS(ifp)->v_wait = EIGRP_HOLD_INTERVAL_DEFAULT; + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + + ei->params.v_wait = EIGRP_HOLD_INTERVAL_DEFAULT; return CMD_SUCCESS; } -static int str2auth_type(const char *str, struct interface *ifp) +static int str2auth_type(const char *str, struct eigrp_interface *ei) { /* Sanity check. */ if (str == NULL) return CMD_WARNING_CONFIG_FAILED; if (strncmp(str, "md5", 3) == 0) { - IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_MD5; + ei->params.auth_type = EIGRP_AUTH_TYPE_MD5; return CMD_SUCCESS; } else if (strncmp(str, "hmac-sha-256", 12) == 0) { - IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256; + ei->params.auth_type = EIGRP_AUTH_TYPE_SHA256; return CMD_SUCCESS; } @@ -877,6 +920,7 @@ DEFUN (eigrp_authentication_mode, "HMAC SHA256 algorithm \n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; eigrp = eigrp_lookup(); @@ -885,12 +929,17 @@ DEFUN (eigrp_authentication_mode, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + // if(strncmp(argv[2], "md5",3)) // IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_MD5; // else if(strncmp(argv[2], "hmac-sha-256",12)) // IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256; - return str2auth_type(argv[5]->arg, ifp); + return str2auth_type(argv[5]->arg, ei); } DEFUN (no_eigrp_authentication_mode, @@ -906,6 +955,7 @@ DEFUN (no_eigrp_authentication_mode, "HMAC SHA256 algorithm \n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; eigrp = eigrp_lookup(); @@ -914,7 +964,12 @@ DEFUN (no_eigrp_authentication_mode, return CMD_SUCCESS; } - IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_NONE; + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + + ei->params.auth_type = EIGRP_AUTH_TYPE_NONE; return CMD_SUCCESS; } @@ -930,6 +985,7 @@ DEFUN (eigrp_authentication_keychain, "Name of key-chain\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; struct keychain *keychain; @@ -939,14 +995,19 @@ DEFUN (eigrp_authentication_keychain, return CMD_SUCCESS; } + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + keychain = keychain_lookup(argv[4]->arg); if (keychain != NULL) { - if (IF_DEF_PARAMS(ifp)->auth_keychain) { - free(IF_DEF_PARAMS(ifp)->auth_keychain); - IF_DEF_PARAMS(ifp)->auth_keychain = + if (ei->params.auth_keychain) { + free(ei->params.auth_keychain); + ei->params.auth_keychain = strdup(keychain->name); } else - IF_DEF_PARAMS(ifp)->auth_keychain = + ei->params.auth_keychain = strdup(keychain->name); } else vty_out(vty, "Key chain with specified name not found\n"); @@ -966,6 +1027,7 @@ DEFUN (no_eigrp_authentication_keychain, "Name of key-chain\n") { VTY_DECLVAR_CONTEXT(interface, ifp); + struct eigrp_interface *ei = ifp->info; struct eigrp *eigrp; eigrp = eigrp_lookup(); @@ -974,10 +1036,15 @@ DEFUN (no_eigrp_authentication_keychain, return CMD_SUCCESS; } - if ((IF_DEF_PARAMS(ifp)->auth_keychain != NULL) - && (strcmp(IF_DEF_PARAMS(ifp)->auth_keychain, argv[5]->arg) == 0)) { - free(IF_DEF_PARAMS(ifp)->auth_keychain); - IF_DEF_PARAMS(ifp)->auth_keychain = NULL; + if (!ei) { + vty_out(vty, " EIGRP not configured on this interface\n"); + return CMD_SUCCESS; + } + + if ((ei->params.auth_keychain != NULL) + && (strcmp(ei->params.auth_keychain, argv[5]->arg) == 0)) { + free(ei->params.auth_keychain); + ei->params.auth_keychain = NULL; } else vty_out(vty, "Key chain with specified name not configured on interface\n"); diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 95d97cf97f..28d2f29811 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -148,15 +148,16 @@ static int eigrp_interface_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; + struct eigrp_interface *ei; ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); - assert(ifp->info); + if (!ifp->info) + return 0; - if (!EIGRP_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) { - SET_IF_PARAM(IF_DEF_PARAMS(ifp), type); - IF_DEF_PARAMS(ifp)->type = eigrp_default_iftype(ifp); - } + ei = ifp->info; + + ei->params.type = eigrp_default_iftype(ifp); eigrp_if_update(ifp); @@ -168,7 +169,6 @@ static int eigrp_interface_delete(int command, struct zclient *zclient, { struct interface *ifp; struct stream *s; - struct route_node *rn; s = zclient->ibuf; /* zebra_interface_state_read () updates interface structure in iflist @@ -188,12 +188,11 @@ static int eigrp_interface_delete(int command, struct zclient *zclient, ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) - if (rn->info) - eigrp_if_free((struct eigrp_interface *)rn->info, - INTERFACE_DOWN_BY_ZEBRA); + if (ifp->info) + eigrp_if_free(ifp->info, + INTERFACE_DOWN_BY_ZEBRA); - ifp->ifindex = IFINDEX_INTERNAL; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } @@ -225,8 +224,6 @@ static int eigrp_interface_address_delete(int command, struct zclient *zclient, struct connected *c; struct interface *ifp; struct eigrp_interface *ei; - struct route_node *rn; - struct prefix p; c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); @@ -241,17 +238,9 @@ static int eigrp_interface_address_delete(int command, struct zclient *zclient, } ifp = c->ifp; - p = *c->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_lookup(IF_OIFS(ifp), &p); - if (!rn) { - connected_free(c); + ei = ifp->info; + if (!ei) return 0; - } - - assert(rn->info); - ei = rn->info; /* Call interface hook functions to clean up */ eigrp_if_free(ei, INTERFACE_DOWN_BY_ZEBRA); @@ -265,8 +254,6 @@ static int eigrp_interface_state_up(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; - struct eigrp_interface *ei; - struct route_node *rn; ifp = zebra_interface_if_lookup(zclient->ibuf); @@ -314,12 +301,8 @@ static int eigrp_interface_state_up(int command, struct zclient *zclient, zlog_debug("Zebra: Interface[%s] state change to up.", ifp->name); - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { - if ((ei = rn->info) == NULL) - continue; - - eigrp_if_up(ei); - } + if (ifp->info) + eigrp_if_up(ifp->info); return 0; } @@ -328,8 +311,6 @@ static int eigrp_interface_state_down(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; - struct eigrp_interface *ei; - struct route_node *node; ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); @@ -340,11 +321,8 @@ static int eigrp_interface_state_down(int command, struct zclient *zclient, zlog_debug("Zebra: Interface[%s] state change to down.", ifp->name); - for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) { - if ((ei = node->info) == NULL) - continue; - eigrp_if_down(ei); - } + if (ifp->info) + eigrp_if_down(ifp->info); return 0; } @@ -357,8 +335,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s) stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); /* And look it up. */ - return if_lookup_by_name_len( - ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT); + return if_lookup_by_name(ifname_tmp, VRF_DEFAULT); } void eigrp_zebra_route_add(struct prefix *p, struct list *successors) diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index ee60898f86..a8173f4efd 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -94,8 +94,8 @@ extern struct in_addr router_id_zebra; */ void eigrp_router_id_update(struct eigrp *eigrp) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; u_int32_t router_id, router_id_old; router_id_old = eigrp->router_id; @@ -116,7 +116,7 @@ void eigrp_router_id_update(struct eigrp *eigrp) // inet_ntoa(eigrp->router_id)); /* update eigrp_interface's */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) eigrp_if_update(ifp); } } @@ -282,10 +282,10 @@ void eigrp_finish_final(struct eigrp *eigrp) THREAD_OFF(eigrp->t_read); close(eigrp->fd); - list_delete(eigrp->eiflist); - list_delete(eigrp->oi_write_q); - list_delete(eigrp->topology_changes_externalIPV4); - list_delete(eigrp->topology_changes_internalIPV4); + list_delete_and_null(&eigrp->eiflist); + list_delete_and_null(&eigrp->oi_write_q); + list_delete_and_null(&eigrp->topology_changes_externalIPV4); + list_delete_and_null(&eigrp->topology_changes_internalIPV4); eigrp_topology_cleanup(eigrp->topology_table); eigrp_topology_free(eigrp->topology_table); diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 0afa65d726..c8b9a66e29 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -214,13 +214,11 @@ void isis_adj_state_change(struct isis_adjacency *adj, } else if (new_state == ISIS_ADJ_DOWN) { listnode_delete(circuit->u.bc.adjdb[level - 1], adj); + circuit->upadjcount[level - 1]--; - if (circuit->upadjcount[level - 1] == 0) { - /* Clean lsp_queue when no adj is up. */ - if (circuit->lsp_queue) - list_delete_all_node( - circuit->lsp_queue); - } + if (circuit->upadjcount[level - 1] == 0) + isis_circuit_lsp_queue_clean(circuit); + isis_event_adjacency_state_change(adj, new_state); del = true; @@ -270,12 +268,9 @@ void isis_adj_state_change(struct isis_adjacency *adj, if (adj->circuit->u.p2p.neighbor == adj) adj->circuit->u.p2p.neighbor = NULL; circuit->upadjcount[level - 1]--; - if (circuit->upadjcount[level - 1] == 0) { - /* Clean lsp_queue when no adj is up. */ - if (circuit->lsp_queue) - list_delete_all_node( - circuit->lsp_queue); - } + if (circuit->upadjcount[level - 1] == 0) + isis_circuit_lsp_queue_clean(circuit); + isis_event_adjacency_state_change(adj, new_state); del = true; diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 1a978ee042..5e4090facc 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -45,6 +45,7 @@ #include "isisd/isis_flags.h" #include "isisd/isis_circuit.h" #include "isisd/isis_lsp.h" +#include "isisd/isis_lsp_hash.h" #include "isisd/isis_pdu.h" #include "isisd/isis_network.h" #include "isisd/isis_misc.h" @@ -452,19 +453,19 @@ void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp) if (circuit->ip_addrs) { assert(listcount(circuit->ip_addrs) == 0); - list_delete(circuit->ip_addrs); + list_delete_and_null(&circuit->ip_addrs); circuit->ip_addrs = NULL; } if (circuit->ipv6_link) { assert(listcount(circuit->ipv6_link) == 0); - list_delete(circuit->ipv6_link); + list_delete_and_null(&circuit->ipv6_link); circuit->ipv6_link = NULL; } if (circuit->ipv6_non_link) { assert(listcount(circuit->ipv6_non_link) == 0); - list_delete(circuit->ipv6_non_link); + list_delete_and_null(&circuit->ipv6_non_link); circuit->ipv6_non_link = NULL; } @@ -674,7 +675,8 @@ int isis_circuit_up(struct isis_circuit *circuit) isis_circuit_prepare(circuit); circuit->lsp_queue = list_new(); - circuit->lsp_queue_last_cleared = time(NULL); + circuit->lsp_hash = isis_lsp_hash_new(); + monotime(&circuit->lsp_queue_last_cleared); return ISIS_OK; } @@ -690,22 +692,22 @@ void isis_circuit_down(struct isis_circuit *circuit) if (circuit->circ_type == CIRCUIT_T_BROADCAST) { /* destroy neighbour lists */ if (circuit->u.bc.lan_neighs[0]) { - list_delete(circuit->u.bc.lan_neighs[0]); + list_delete_and_null(&circuit->u.bc.lan_neighs[0]); circuit->u.bc.lan_neighs[0] = NULL; } if (circuit->u.bc.lan_neighs[1]) { - list_delete(circuit->u.bc.lan_neighs[1]); + list_delete_and_null(&circuit->u.bc.lan_neighs[1]); circuit->u.bc.lan_neighs[1] = NULL; } /* destroy adjacency databases */ if (circuit->u.bc.adjdb[0]) { circuit->u.bc.adjdb[0]->del = isis_delete_adj; - list_delete(circuit->u.bc.adjdb[0]); + list_delete_and_null(&circuit->u.bc.adjdb[0]); circuit->u.bc.adjdb[0] = NULL; } if (circuit->u.bc.adjdb[1]) { circuit->u.bc.adjdb[1]->del = isis_delete_adj; - list_delete(circuit->u.bc.adjdb[1]); + list_delete_and_null(&circuit->u.bc.adjdb[1]); circuit->u.bc.adjdb[1] = NULL; } if (circuit->u.bc.is_dr[0]) { @@ -739,12 +741,16 @@ void isis_circuit_down(struct isis_circuit *circuit) THREAD_TIMER_OFF(circuit->t_send_csnp[1]); THREAD_TIMER_OFF(circuit->t_send_psnp[0]); THREAD_TIMER_OFF(circuit->t_send_psnp[1]); + THREAD_OFF(circuit->t_send_lsp); THREAD_OFF(circuit->t_read); if (circuit->lsp_queue) { - circuit->lsp_queue->del = NULL; - list_delete(circuit->lsp_queue); - circuit->lsp_queue = NULL; + list_delete_and_null(&circuit->lsp_queue); + } + + if (circuit->lsp_hash) { + isis_lsp_hash_free(circuit->lsp_hash); + circuit->lsp_hash = NULL; } /* send one gratuitous hello to spead up convergence */ @@ -926,17 +932,15 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, int isis_interface_config_write(struct vty *vty) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int write = 0; - struct listnode *node, *node2; + struct listnode *node; struct interface *ifp; struct isis_area *area; struct isis_circuit *circuit; int i; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { - if (ifp->ifindex == IFINDEX_DELETED) - continue; - + FOR_ALL_INTERFACES (vrf, ifp) { /* IF name */ vty_frame(vty, "interface %s\n", ifp->name); write++; @@ -946,7 +950,7 @@ int isis_interface_config_write(struct vty *vty) write++; } /* ISIS Circuit */ - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node2, area)) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); if (circuit == NULL) @@ -1339,3 +1343,56 @@ void isis_circuit_init() isis_vty_init(); } + +void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit) +{ + if (circuit->t_send_lsp) + return; + circuit->t_send_lsp = thread_add_event(master, send_lsp, circuit, 0, NULL); +} + +void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp) +{ + if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp)) + return; + + listnode_add(circuit->lsp_queue, lsp); + isis_lsp_hash_add(circuit->lsp_hash, lsp); + isis_circuit_schedule_lsp_send(circuit); +} + +void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit) +{ + if (!circuit->lsp_queue) + return; + + list_delete_all_node(circuit->lsp_queue); + isis_lsp_hash_clean(circuit->lsp_hash); +} + +void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit, + struct isis_lsp *lsp) +{ + if (!circuit->lsp_queue) + return; + + listnode_delete(circuit->lsp_queue, lsp); + isis_lsp_hash_release(circuit->lsp_hash, lsp); +} + +struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit) +{ + if (!circuit->lsp_queue) + return NULL; + + struct listnode *node = listhead(circuit->lsp_queue); + if (!node) + return NULL; + + struct isis_lsp *rv = listgetdata(node); + + list_delete_node(circuit->lsp_queue, node); + isis_lsp_hash_release(circuit->lsp_hash, rv); + + return rv; +} diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 5906efd2b8..29694deb34 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -34,6 +34,8 @@ #define CIRCUIT_MAX 255 +struct isis_lsp; + struct password { struct password *next; int len; @@ -79,8 +81,10 @@ struct isis_circuit { struct thread *t_read; struct thread *t_send_csnp[2]; struct thread *t_send_psnp[2]; + struct thread *t_send_lsp; struct list *lsp_queue; /* LSPs to be txed (both levels) */ - time_t lsp_queue_last_cleared; /* timestamp used to enforce transmit + struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */ + struct timeval lsp_queue_last_cleared; /* timestamp used to enforce transmit * interval; * for scalability, use one timestamp per * circuit, instead of one per lsp per @@ -195,4 +199,10 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, bool enabled); +void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit); +void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp); +void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit); +void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit, + struct isis_lsp *lsp); +struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit); #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_constants.h b/isisd/isis_constants.h index f3a5a24dde..b7b5d35c2e 100644 --- a/isisd/isis_constants.h +++ b/isisd/isis_constants.h @@ -73,7 +73,7 @@ #define MAX_MIN_LSP_GEN_INTERVAL 120 /* RFC 4444 says 65535 */ #define DEFAULT_MIN_LSP_GEN_INTERVAL 30 -#define MIN_LSP_TRANS_INTERVAL 5 +#define MIN_LSP_TRANS_INTERVAL 20000 /* Microseconds */ #define MIN_CSNP_INTERVAL 1 #define MAX_CSNP_INTERVAL 600 diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c index 2db8271915..84b0bb9739 100644 --- a/isisd/isis_dr.c +++ b/isisd/isis_dr.c @@ -135,7 +135,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level) if (!adjdb) { zlog_warn("isis_dr_elect() adjdb == NULL"); - list_delete(list); + list_delete_and_null(&list); return ISIS_WARNING; } isis_adj_build_up_list(adjdb, list); @@ -177,7 +177,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level) */ if (circuit->u.bc.is_dr[level - 1]) retval = isis_dr_resign(circuit, level); - list_delete(list); + list_delete_and_null(&list); return retval; } @@ -217,7 +217,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level) if (circuit->u.bc.is_dr[level - 1]) retval = isis_dr_resign(circuit, level); } - list_delete(list); + list_delete_and_null(&list); return retval; } diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 1cc90d031c..bc35439926 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -132,10 +132,8 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level) THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]); circuit->lsp_regenerate_pending[idx] = 0; circuit->u.bc.run_dr_elect[idx] = 0; - if (circuit->u.bc.lan_neighs[idx] != NULL) { - list_delete(circuit->u.bc.lan_neighs[idx]); - circuit->u.bc.lan_neighs[idx] = NULL; - } + if (circuit->u.bc.lan_neighs[idx] != NULL) + list_delete_and_null(&circuit->u.bc.lan_neighs[idx]); } return; diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 33c52804e4..07579446aa 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -111,32 +111,22 @@ static void lsp_clear_data(struct isis_lsp *lsp) static void lsp_destroy(struct isis_lsp *lsp) { - struct listnode *cnode, *lnode, *lnnode; - struct isis_lsp *lsp_in_list; + struct listnode *cnode; struct isis_circuit *circuit; if (!lsp) return; - if (lsp->area->circuit_list) { - for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, - circuit)) { - if (circuit->lsp_queue == NULL) - continue; - for (ALL_LIST_ELEMENTS(circuit->lsp_queue, lnode, - lnnode, lsp_in_list)) - if (lsp_in_list == lsp) - list_delete_node(circuit->lsp_queue, - lnode); - } - } + for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit)) + isis_circuit_cancel_queued_lsp(circuit, lsp); + ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); lsp_clear_data(lsp); if (LSP_FRAGMENT(lsp->hdr.lsp_id) == 0 && lsp->lspu.frags) { - list_delete(lsp->lspu.frags); + list_delete_and_null(&lsp->lspu.frags); lsp->lspu.frags = NULL; } @@ -1153,7 +1143,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) frag->tlvs = tlvs; } - list_delete(fragments); + list_delete_and_null(&fragments); lsp_debug("ISIS (%s): LSP construction is complete. Serializing...", area->area_tag); return; @@ -1531,7 +1521,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit, LSP_PSEUDO_ID(ne_id)); } } - list_delete(adj_list); + list_delete_and_null(&adj_list); return; } @@ -1890,12 +1880,15 @@ int lsp_tick(struct thread *thread) if (listcount(lsp_list) > 0) { for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) { - int diff = - time(NULL) - - circuit->lsp_queue_last_cleared; - if (circuit->lsp_queue == NULL - || diff < MIN_LSP_TRANS_INTERVAL) + if (!circuit->lsp_queue) continue; + + if (monotime_since( + &circuit->lsp_queue_last_cleared, + NULL) < MIN_LSP_TRANS_INTERVAL) { + continue; + } + for (ALL_LIST_ELEMENTS_RO( lsp_list, lspnode, lsp)) { if (circuit->upadjcount @@ -1903,23 +1896,7 @@ int lsp_tick(struct thread *thread) && ISIS_CHECK_FLAG( lsp->SRMflags, circuit)) { - /* Add the lsp only if - * it is not already in - * lsp - * queue */ - if (!listnode_lookup( - circuit->lsp_queue, - lsp)) { - listnode_add( - circuit->lsp_queue, - lsp); - thread_add_event( - master, - send_lsp, - circuit, - 0, - NULL); - } + isis_circuit_queue_lsp(circuit, lsp); } } } @@ -1928,7 +1905,7 @@ int lsp_tick(struct thread *thread) } } - list_delete(lsp_list); + list_delete_and_null(&lsp_list); return ISIS_OK; } diff --git a/isisd/isis_lsp_hash.c b/isisd/isis_lsp_hash.c new file mode 100644 index 0000000000..9196128828 --- /dev/null +++ b/isisd/isis_lsp_hash.c @@ -0,0 +1,89 @@ +/* + * IS-IS Rout(e)ing protocol - LSP Hash + * + * Copyright (C) 2017 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#include "hash.h" +#include "jhash.h" + +#include "isisd/isis_memory.h" +#include "isisd/isis_flags.h" +#include "dict.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_lsp.h" +#include "isisd/isis_lsp_hash.h" + +DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash") + +struct isis_lsp_hash { + struct hash *h; +}; + +static unsigned lsp_hash_key(void *lp) +{ + struct isis_lsp *lsp = lp; + + return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a); +} + +static int lsp_hash_cmp(const void *a, const void *b) +{ + const struct isis_lsp *la = a, *lb = b; + + return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2); +} + +struct isis_lsp_hash *isis_lsp_hash_new(void) +{ + struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv)); + + rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL); + return rv; +} + +void isis_lsp_hash_clean(struct isis_lsp_hash *ih) +{ + hash_clean(ih->h, NULL); +} + +void isis_lsp_hash_free(struct isis_lsp_hash *ih) +{ + isis_lsp_hash_clean(ih); + hash_free(ih->h); +} + +struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, + struct isis_lsp *lsp) +{ + return hash_lookup(ih->h, lsp); +} + +void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp) +{ + struct isis_lsp *inserted; + inserted = hash_get(ih->h, lsp, hash_alloc_intern); + assert(inserted == lsp); +} + +void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp) +{ + hash_release(ih->h, lsp); +} diff --git a/isisd/isis_lsp_hash.h b/isisd/isis_lsp_hash.h new file mode 100644 index 0000000000..b50aa09dc1 --- /dev/null +++ b/isisd/isis_lsp_hash.h @@ -0,0 +1,34 @@ +/* + * IS-IS Rout(e)ing protocol - LSP Hash + * + * Copyright (C) 2017 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef ISIS_LSP_HASH_H +#define ISIS_LSP_HASH_H + +struct isis_lsp_hash; + +struct isis_lsp_hash *isis_lsp_hash_new(void); +void isis_lsp_hash_clean(struct isis_lsp_hash *ih); +void isis_lsp_hash_free(struct isis_lsp_hash *ih); +struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, + struct isis_lsp *lsp); +void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp); +void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp); +#endif diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index 52646c2624..d13f2a13f3 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -151,8 +151,7 @@ void area_mt_init(struct isis_area *area) void area_mt_finish(struct isis_area *area) { - list_delete(area->mt_settings); - area->mt_settings = NULL; + list_delete_and_null(&area->mt_settings); } struct isis_area_mt_setting *area_get_mt_setting(struct isis_area *area, @@ -275,8 +274,7 @@ void circuit_mt_init(struct isis_circuit *circuit) void circuit_mt_finish(struct isis_circuit *circuit) { - list_delete(circuit->mt_settings); - circuit->mt_settings = NULL; + list_delete_and_null(&circuit->mt_settings); } struct isis_circuit_mt_setting * diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index a20051f8c3..9c68fe5966 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1292,7 +1292,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) ISIS_SET_FLAG(lsp->SRMflags, circuit); /* lets free it */ - list_delete(lsp_list); + list_delete_and_null(&lsp_list); } retval = ISIS_OK; @@ -1546,8 +1546,11 @@ int send_hello(struct isis_circuit *circuit, int level) isis_tlvs_add_auth(tlvs, &circuit->passwd); - if (!listcount(circuit->area->area_addrs)) + if (!listcount(circuit->area->area_addrs)) { + isis_free_tlvs(tlvs); return ISIS_WARNING; + } + isis_tlvs_add_area_addresses(tlvs, circuit->area->area_addrs); if (circuit->circ_type == CIRCUIT_T_BROADCAST) @@ -2046,39 +2049,24 @@ int send_lsp(struct thread *thread) { struct isis_circuit *circuit; struct isis_lsp *lsp; - struct listnode *node; int clear_srm = 1; int retval = ISIS_OK; circuit = THREAD_ARG(thread); assert(circuit); + circuit->t_send_lsp = NULL; - if (!circuit->lsp_queue) - return ISIS_OK; - - node = listhead(circuit->lsp_queue); - - /* - * Handle case where there are no LSPs on the queue. This can - * happen, for instance, if an adjacency goes down before this - * thread gets a chance to run. - */ - if (!node) + lsp = isis_circuit_lsp_queue_pop(circuit); + if (!lsp) return ISIS_OK; - - /* - * Delete LSP from lsp_queue. If it's still in queue, it is assumed - * as 'transmit pending', but send_lsp may never be called again. - * Retry will happen because SRM flag will not be cleared. - */ - lsp = listgetdata(node); - list_delete_node(circuit->lsp_queue, node); - /* Set the last-cleared time if the queue is empty. */ /* TODO: Is is possible that new lsps keep being added to the queue * that the queue is never empty? */ - if (list_isempty(circuit->lsp_queue)) - circuit->lsp_queue_last_cleared = time(NULL); + if (list_isempty(circuit->lsp_queue)) { + monotime(&circuit->lsp_queue_last_cleared); + } else { + isis_circuit_schedule_lsp_send(circuit); + } if (circuit->state != C_STATE_UP || circuit->is_passive == 1) goto out; diff --git a/isisd/isis_route.c b/isisd/isis_route.c index ff17572ef9..b9605018ed 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -289,13 +289,13 @@ static void isis_route_info_delete(struct isis_route_info *route_info) if (route_info->nexthops) { route_info->nexthops->del = (void (*)(void *))isis_nexthop_delete; - list_delete(route_info->nexthops); + list_delete_and_null(&route_info->nexthops); } if (route_info->nexthops6) { route_info->nexthops6->del = (void (*)(void *))isis_nexthop6_delete; - list_delete(route_info->nexthops6); + list_delete_and_null(&route_info->nexthops6); } XFREE(MTYPE_ISIS_ROUTE_INFO, route_info); diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index cd9a0f89bb..3008fb6a1e 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -205,10 +205,8 @@ static void isis_vertex_queue_free(struct isis_vertex_queue *queue) if (queue->insert_counter) { skiplist_free(queue->l.slist); queue->l.slist = NULL; - } else { - list_delete(queue->l.list); - queue->l.list = NULL; - } + } else + list_delete_and_null(&queue->l.list); } static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue) @@ -437,10 +435,8 @@ static struct isis_vertex *isis_vertex_new(void *id, enum vertextype vtype) static void isis_vertex_del(struct isis_vertex *vertex) { - list_delete(vertex->Adj_N); - vertex->Adj_N = NULL; - list_delete(vertex->parents); - vertex->parents = NULL; + list_delete_and_null(&vertex->Adj_N); + list_delete_and_null(&vertex->parents); memset(vertex, 0, sizeof(struct isis_vertex)); XFREE(MTYPE_ISIS_VERTEX, vertex); @@ -1038,7 +1034,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, adjdb = circuit->u.bc.adjdb[spftree->level - 1]; isis_adj_build_up_list(adjdb, adj_list); if (listcount(adj_list) == 0) { - list_delete(adj_list); + list_delete_and_null(&adj_list); if (isis->debugs & DEBUG_SPF_EVENTS) zlog_debug( "ISIS-Spf: no L%d adjacencies on circuit %s", @@ -1102,7 +1098,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, "isis_spf_preload_tent unknow adj type"); } } - list_delete(adj_list); + list_delete_and_null(&adj_list); /* * Add the pseudonode */ diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 70afef1a86..104a0fd4bf 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -223,6 +223,9 @@ uint8_t add_te_subtlvs(uint8_t *buf, struct mpls_te_circuit *mtc) tlvs += size; } + /* Add before this line any other parsing of TLV */ + (void)tlvs; + /* Update SubTLVs length */ mtc->length = subtlvs_len(mtc); @@ -1242,13 +1245,13 @@ DEFUN (show_isis_mpls_te_interface, "Interface information\n" "Interface name\n") { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int idx_interface = 4; struct interface *ifp; - struct listnode *node; /* Show All Interfaces. */ if (argc == 4) { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) show_mpls_te_sub(vty, ifp); } /* Interface name is specified. */ diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 25a10e91e6..b7389947b7 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -2397,8 +2397,7 @@ struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size) struct listnode *node; for (ALL_LIST_ELEMENTS_RO(rv, node, fragment_tlvs)) isis_free_tlvs(fragment_tlvs); - list_delete(rv); - rv = NULL; + list_delete_and_null(&rv); } stream_free(dummy_stream); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index bc81314097..387f99938e 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -128,7 +128,7 @@ static int isis_zebra_if_del(int command, struct zclient *zclient, in case there is configuration info attached to it. */ if_delete_retain(ifp); - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } diff --git a/isisd/isisd.c b/isisd/isisd.c index bdc1d836db..5dd348089d 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -220,8 +220,7 @@ int isis_area_destroy(struct vty *vty, const char *area_tag) circuit->ipv6_router = 0; isis_csm_state_change(ISIS_DISABLE, circuit, area); } - list_delete(area->circuit_list); - area->circuit_list = NULL; + list_delete_and_null(&area->circuit_list); } if (area->lspdb[0] != NULL) { diff --git a/isisd/subdir.am b/isisd/subdir.am index 6e49d4ec80..7b56715fa9 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -18,6 +18,7 @@ isisd_libisis_a_SOURCES = \ isisd/isis_events.c \ isisd/isis_flags.c \ isisd/isis_lsp.c \ + isisd/isis_lsp_hash.c \ isisd/isis_memory.c \ isisd/isis_misc.c \ isisd/isis_mt.c \ @@ -46,6 +47,7 @@ noinst_HEADERS += \ isisd/isis_events.h \ isisd/isis_flags.h \ isisd/isis_lsp.h \ + isisd/isis_lsp_hash.h \ isisd/isis_memory.h \ isisd/isis_misc.h \ isisd/isis_mt.h \ diff --git a/ldpd/address.c b/ldpd/address.c index 18ab037760..9c1564a31f 100644 --- a/ldpd/address.c +++ b/ldpd/address.c @@ -88,6 +88,7 @@ send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list, err |= gen_msg_hdr(buf, msg_type, size); size -= LDP_MSG_SIZE; err |= gen_address_list_tlv(buf, af, addr_list, tlv_addr_count); + (void)size; if (err) { address_list_clr(addr_list); ibuf_free(buf); @@ -98,6 +99,7 @@ send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list, log_msg_address(1, msg_type, nbr, af, &if_addr->addr); LIST_REMOVE(if_addr, entry); + assert(if_addr != LIST_FIRST(addr_list)); free(if_addr); if (--tlv_addr_count == 0) break; @@ -168,7 +170,6 @@ send_mac_withdrawal(struct nbr *nbr, struct map *fec, uint8_t *mac) err = gen_ldp_hdr(buf, size); size -= LDP_HDR_SIZE; err |= gen_msg_hdr(buf, MSG_TYPE_ADDRWITHDRAW, size); - size -= LDP_MSG_SIZE; err |= gen_address_list_tlv(buf, AF_INET, NULL, 0); err |= gen_fec_tlv(buf, fec); err |= gen_mac_list_tlv(buf, mac); @@ -400,6 +401,7 @@ address_list_clr(struct if_addr_head *addr_list) while ((if_addr = LIST_FIRST(addr_list)) != NULL) { LIST_REMOVE(if_addr, entry); + assert(if_addr != LIST_FIRST(addr_list)); free(if_addr); } } diff --git a/ldpd/interface.c b/ldpd/interface.c index a18019c0c1..bbcea9f553 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -103,6 +103,7 @@ ldpe_if_exit(struct iface *iface) while ((if_addr = LIST_FIRST(&iface->addr_list)) != NULL) { LIST_REMOVE(if_addr, entry); + assert(if_addr != LIST_FIRST(&iface->addr_list)); free(if_addr); } } diff --git a/ldpd/labelmapping.c b/ldpd/labelmapping.c index f53bc8333d..5662038a58 100644 --- a/ldpd/labelmapping.c +++ b/ldpd/labelmapping.c @@ -130,6 +130,7 @@ send_labelmessage(struct nbr *nbr, uint16_t type, struct mapping_head *mh) } TAILQ_REMOVE(mh, me, entry); + assert(me != TAILQ_FIRST(mh)); free(me); } @@ -459,6 +460,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) next: TAILQ_REMOVE(&mh, me, entry); + assert(me != TAILQ_FIRST(&mh)); free(me); } diff --git a/ldpd/lde.c b/ldpd/lde.c index 3482f3d722..a7f933bbe5 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -185,11 +185,14 @@ lde_shutdown(void) if (iev_ldpe) { msgbuf_clear(&iev_ldpe->ibuf.w); close(iev_ldpe->ibuf.fd); + iev_ldpe->ibuf.fd = -1; } msgbuf_clear(&iev_main->ibuf.w); close(iev_main->ibuf.fd); + iev_main->ibuf.fd = -1; msgbuf_clear(&iev_main_sync->ibuf.w); close(iev_main_sync->ibuf.fd); + iev_main_sync->ibuf.fd = -1; lde_gc_stop_timer(); lde_nbr_clear(); @@ -210,12 +213,16 @@ lde_shutdown(void) int lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen) { + if (iev_main->ibuf.fd == -1) + return (0); return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); } void lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen) { + if (iev_main_sync->ibuf.fd == -1) + return; imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen); imsg_flush(&iev_main_sync->ibuf); } @@ -224,6 +231,8 @@ int lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data, uint16_t datalen) { + if (iev_ldpe->ibuf.fd == -1) + return (0); return (imsg_compose_event(iev_ldpe, type, peerid, pid, -1, data, datalen)); } @@ -429,7 +438,7 @@ lde_dispatch_parent(struct thread *thread) struct imsg imsg; struct kif *kif; struct kroute *kr; - int fd = THREAD_FD(thread); + int fd; struct imsgev *iev = THREAD_ARG(thread); struct imsgbuf *ibuf = &iev->ibuf; ssize_t n; diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index c56b7e33d0..18c8c0a122 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -229,8 +229,10 @@ fec_free(void *arg) struct fec_node *fn = arg; struct fec_nh *fnh; - while ((fnh = LIST_FIRST(&fn->nexthops))) + while ((fnh = LIST_FIRST(&fn->nexthops))) { fec_nh_del(fnh); + assert(fnh != LIST_FIRST(&fn->nexthops)); + } if (!RB_EMPTY(lde_map_head, &fn->downstream)) log_warnx("%s: fec %s downstream list not empty", __func__, log_fec(&fn->fec)); diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index c50cc0fda2..7f68f0b694 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -212,13 +212,14 @@ kmpw_unset(struct zapi_pw *zpw) void kif_redistribute(const char *ifname) { - struct listnode *node, *cnode; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct listnode *cnode; struct interface *ifp; struct connected *ifc; struct kif kif; struct kaddr ka; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if (ifname && strcmp(ifname, ifp->name) != 0) continue; @@ -287,7 +288,7 @@ ldp_interface_delete(int command, struct zclient *zclient, zebra_size_t length, /* To support pseudo interface do not free interface structure. */ /* if_delete(ifp); */ - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); ifp2kif(ifp, &kif); main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif)); diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index a79e63229f..12aeb1fff3 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -260,7 +260,6 @@ main(int argc, char *argv[]) sizeof(init.zclient_serv_path)); argc -= optind; - argv += optind; if (argc > 0 || (lflag && eflag)) frr_help_exit(1); @@ -450,10 +449,15 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) } nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); - dup2(nullfd, 0); - dup2(nullfd, 1); - dup2(nullfd, 2); - close(nullfd); + if (nullfd == -1) { + zlog_err("%s: failed to open /dev/null: %s", __func__, + safe_strerror(errno)); + } else { + dup2(nullfd, 0); + dup2(nullfd, 1); + dup2(nullfd, 2); + close(nullfd); + } if (dup2(fd_async, LDPD_FD_ASYNC) == -1) fatal("cannot setup imsg async fd"); diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index 1c0a8bdc84..9d00bcd2b6 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -190,15 +190,16 @@ ldpe_shutdown(void) /* close pipes */ if (iev_lde) { - msgbuf_write(&iev_lde->ibuf.w); msgbuf_clear(&iev_lde->ibuf.w); close(iev_lde->ibuf.fd); + iev_lde->ibuf.fd = -1; } - msgbuf_write(&iev_main->ibuf.w); msgbuf_clear(&iev_main->ibuf.w); close(iev_main->ibuf.fd); + iev_main->ibuf.fd = -1; msgbuf_clear(&iev_main_sync->ibuf.w); close(iev_main_sync->ibuf.fd); + iev_main_sync->ibuf.fd = -1; control_cleanup(ctl_sock_path); config_clear(leconf); @@ -215,6 +216,7 @@ ldpe_shutdown(void) /* remove addresses from global list */ while ((if_addr = LIST_FIRST(&global.addr_list)) != NULL) { LIST_REMOVE(if_addr, entry); + assert(if_addr != LIST_FIRST(&global.addr_list)); free(if_addr); } while ((adj = RB_ROOT(global_adj_head, &global.adj_tree)) != NULL) @@ -235,12 +237,16 @@ ldpe_shutdown(void) int ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen) { + if (iev_main->ibuf.fd == -1) + return (0); return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); } void ldpe_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen) { + if (iev_main_sync->ibuf.fd == -1) + return; imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen); imsg_flush(&iev_main_sync->ibuf); } @@ -249,6 +255,8 @@ int ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data, uint16_t datalen) { + if (iev_lde->ibuf.fd == -1) + return (0); return (imsg_compose_event(iev_lde, type, peerid, pid, -1, data, datalen)); } @@ -265,7 +273,7 @@ ldpe_dispatch_main(struct thread *thread) struct l2vpn_if *lif, *nlif; struct l2vpn_pw *pw, *npw; struct imsg imsg; - int fd = THREAD_FD(thread); + int fd; struct imsgev *iev = THREAD_ARG(thread); struct imsgbuf *ibuf = &iev->ibuf; struct iface *iface = NULL; @@ -964,6 +972,7 @@ mapping_list_clr(struct mapping_head *mh) while ((me = TAILQ_FIRST(mh)) != NULL) { TAILQ_REMOVE(mh, me, entry); + assert(me != TAILQ_FIRST(mh)); free(me); } } diff --git a/ldpd/packet.c b/ldpd/packet.c index be7f2ba649..4a4b258b91 100644 --- a/ldpd/packet.c +++ b/ldpd/packet.c @@ -494,7 +494,7 @@ session_read(struct thread *thread) msg_len = ntohs(msg->length); if (msg_len < LDP_MSG_LEN || (msg_len + LDP_MSG_DEAD_LEN) > pdu_len) { - session_shutdown(nbr, S_BAD_TLV_LEN, msg->id, + session_shutdown(nbr, S_BAD_MSG_LEN, msg->id, msg->type); free(buf); return (0); diff --git a/lib/command.c b/lib/command.c index d1b0867372..97eba96c3a 100644 --- a/lib/command.c +++ b/lib/command.c @@ -686,7 +686,7 @@ static vector cmd_complete_command_real(vector vline, struct vty *vty, } vector comps = completions_to_vec(completions); - list_delete(completions); + list_delete_and_null(&completions); // set status code appropriately switch (vector_active(comps)) { @@ -1006,7 +1006,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter, // if matcher error, return corresponding CMD_ERR if (MATCHER_ERROR(status)) { if (argv_list) - list_delete(argv_list); + list_delete_and_null(&argv_list); switch (status) { case MATCHER_INCOMPLETE: return CMD_ERR_INCOMPLETE; @@ -1035,7 +1035,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter, ret = matched_element->func(matched_element, vty, argc, argv); // delete list and cmd_token's in it - list_delete(argv_list); + list_delete_and_null(&argv_list); XFREE(MTYPE_TMP, argv); return ret; @@ -2730,6 +2730,6 @@ void cmd_terminate() if (host.config) XFREE(MTYPE_HOST, host.config); - list_delete(varhandlers); + list_delete_and_null(&varhandlers); qobj_finish(); } diff --git a/lib/command.h b/lib/command.h index 8cccb62de3..e2d31decd4 100644 --- a/lib/command.h +++ b/lib/command.h @@ -380,6 +380,13 @@ extern void uninstall_element(enum node_type, struct cmd_element *); string with a space between each element (allocated using XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */ extern char *argv_concat(struct cmd_token **argv, int argc, int shift); + +/* + * It is preferred that you set the index initial value + * to a 0. This way in the future if you modify the + * cli then there is no need to modify the initial + * value of the index + */ extern int argv_find(struct cmd_token **argv, int argc, const char *text, int *index); diff --git a/lib/command_match.c b/lib/command_match.c index 6384abe5ce..c60373f910 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -333,7 +333,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline, status = MATCHER_INCOMPLETE; // cleanup - list_delete(next); + list_delete_and_null(&next); return status; } @@ -366,7 +366,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, unsigned int idx; for (idx = 0; idx < vector_active(vline) && next->count > 0; idx++) { - list_delete(current); + list_delete_and_null(¤t); current = next; next = list_new(); next->del = stack_del; @@ -457,8 +457,8 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, } } - list_delete(current); - list_delete(next); + list_delete_and_null(¤t); + list_delete_and_null(&next); return mrv; } @@ -648,7 +648,7 @@ static void del_arglist(struct list *list) list_delete_node(list, tail); // delete the rest of the list as usual - list_delete(list); + list_delete_and_null(&list); } /*---------- token level matching functions ----------*/ @@ -284,6 +284,11 @@ csv_record_t *csv_encode_record(csv_t *csv, csv_record_t *rec, int count, ...) va_start(list, count); str = csv_field_iter(rec, &fld); + if (!fld) { + va_end(list); + return NULL; + } + for (tempc = 0; tempc < count; tempc++) { col = va_arg(list, char *); for (i = 0; i < fld->field_len; i++) { @@ -652,18 +657,15 @@ int main() { char buf[10000]; csv_t csv; - int p; - int i, j; + int i; csv_record_t *rec; - csv_field_t *fld; - char *str; char hdr1[32], hdr2[32]; - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); + log_verbose("Mem: %d\n", get_memory_usage(getpid())); csv_init(&csv, buf, 256); sprintf(hdr1, "%4u", 0); sprintf(hdr2, "%4u", 1); - log_verbose("(%d/%d/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), + log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), atoi(hdr2)); rec = csv_encode(&csv, 2, hdr1, hdr2); csv_encode(&csv, 4, "name", "age", "sex", "hei"); @@ -676,19 +678,19 @@ int main() log_verbose("%s\n", buf); sprintf(hdr1, "%4u", csv.csv_len); sprintf(hdr2, "%4u", 1); - log_verbose("(%d/%d/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), + log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), atoi(hdr2)); rec = csv_encode_record(&csv, rec, 2, hdr1, hdr2); log_verbose("(%d/%d)\n%s\n", rec->rec_len, csv.csv_len, buf); - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); + log_verbose("Mem: %d\n", get_memory_usage(getpid())); csv_clean(&csv); - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); + log_verbose("Mem: %d\n", get_memory_usage(getpid())); csv_init(&csv, buf, 256); csv_decode(&csv, NULL); - log_verbose("AFTER DECODE\n"); + log_verbose("%s", "AFTER DECODE\n"); csv_dump(&csv); csv_clean(&csv); - log_verbose("Mem: %ld\n", get_memory_usage(getpid())); + log_verbose("Mem: %d\n", get_memory_usage(getpid())); } #endif diff --git a/lib/ferr.c b/lib/ferr.c index 2a039d2089..69aeb3db40 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -74,6 +74,7 @@ static ferr_r ferr_set_va(const char *file, int line, const char *func, /* we're screwed */ zlog_err("out of memory while allocating error info"); raise(SIGSEGV); + abort(); /* raise() can return, but raise(SIGSEGV) shall not */ } pthread_setspecific(errkey, error); diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 3c6396f347..66b042ad97 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -141,7 +141,7 @@ DEFUN (grammar_test_complete, vty_out(vty, "%% No match\n"); // free resources - list_delete(completions); + list_delete_and_null(&completions); cmd_free_strvec(command); XFREE(MTYPE_TMP, cmdstr); @@ -185,7 +185,7 @@ DEFUN (grammar_test_match, vty_out(vty, "func: %p\n", element->func); - list_delete(argvv); + list_delete_and_null(&argvv); } else { assert(MATCHER_ERROR(result)); switch (result) { @@ -426,7 +426,7 @@ DEFUN (grammar_findambig, } prev = cur; } - list_delete(commands); + list_delete_and_null(&commands); vty_out(vty, "\n"); } while (scan && scannode < LINK_PARAMS_NODE); diff --git a/lib/hash.c b/lib/hash.c index 243521bef7..d2846d7379 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -318,8 +318,7 @@ void hash_free(struct hash *hash) if (_hashes) { listnode_delete(_hashes, hash); if (_hashes->count == 0) { - list_delete(_hashes); - _hashes = NULL; + list_delete_and_null(&_hashes); } } } @@ -40,6 +40,12 @@ DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected") DEFINE_MTYPE(LIB, CONNECTED_LABEL, "Connected interface label") DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters") +static int if_cmp_func(const struct interface *, const struct interface *); +static int if_cmp_index_func(const struct interface *ifp1, + const struct interface *ifp2); +RB_GENERATE(if_name_head, interface, name_entry, if_cmp_func); +RB_GENERATE(if_index_head, interface, index_entry, if_cmp_index_func); + DEFINE_QOBJ_TYPE(interface) DEFINE_HOOK(if_add, (struct interface *ifp), (ifp)) @@ -85,6 +91,8 @@ int if_cmp_name_func(char *p1, char *p2) p1 += l1; p2 += l1; + if (!*p1 && !*p2) + return 0; if (!*p1) return -1; if (!*p2) @@ -109,32 +117,31 @@ int if_cmp_name_func(char *p1, char *p2) return 0; } -static int if_cmp_func(struct interface *ifp1, struct interface *ifp2) +static int if_cmp_func(const struct interface *ifp1, + const struct interface *ifp2) +{ + return if_cmp_name_func((char *)ifp1->name, (char *)ifp2->name); +} + +static int if_cmp_index_func(const struct interface *ifp1, + const struct interface *ifp2) { - return if_cmp_name_func(ifp1->name, ifp2->name); + return ifp1->ifindex - ifp2->ifindex; } /* Create new interface structure. */ -struct interface *if_create(const char *name, int namelen, vrf_id_t vrf_id) +struct interface *if_create(const char *name, vrf_id_t vrf_id) { + struct vrf *vrf = vrf_get(vrf_id, NULL); struct interface *ifp; - struct list *intf_list = vrf_iflist_get(vrf_id); ifp = XCALLOC(MTYPE_IF, sizeof(struct interface)); ifp->ifindex = IFINDEX_INTERNAL; assert(name); - assert(namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */ - strncpy(ifp->name, name, namelen); - ifp->name[namelen] = '\0'; + strlcpy(ifp->name, name, sizeof(ifp->name)); ifp->vrf_id = vrf_id; - if (if_lookup_by_name(ifp->name, vrf_id) == NULL) - listnode_add_sort(intf_list, ifp); - else - zlog_err( - "if_create(%s): corruption detected -- interface with this " - "name exists already in VRF %u!", - ifp->name, vrf_id); + IFNAME_RB_INSERT(vrf, ifp); ifp->connected = list_new(); ifp->connected->del = (void (*)(void *))connected_free; @@ -152,22 +159,22 @@ struct interface *if_create(const char *name, int namelen, vrf_id_t vrf_id) /* Create new interface structure. */ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id) { - struct list *intf_list = vrf_iflist_get(vrf_id); + struct vrf *vrf; /* remove interface from old master vrf list */ - if (vrf_iflist(ifp->vrf_id)) - listnode_delete(vrf_iflist(ifp->vrf_id), ifp); + vrf = vrf_lookup_by_id(ifp->vrf_id); + if (vrf) { + IFNAME_RB_REMOVE(vrf, ifp); + if (ifp->ifindex != IFINDEX_INTERNAL) + IFINDEX_RB_REMOVE(vrf, ifp); + } ifp->vrf_id = vrf_id; - if (if_lookup_by_name(ifp->name, vrf_id) == NULL) - listnode_add_sort(intf_list, ifp); - else - zlog_err( - "if_create(%s): corruption detected -- interface with this " - "name exists already in VRF %u!", - ifp->name, vrf_id); - - return; + vrf = vrf_get(ifp->vrf_id, NULL); + + IFNAME_RB_INSERT(vrf, ifp); + if (ifp->ifindex != IFINDEX_INTERNAL) + IFINDEX_RB_INSERT(vrf, ifp); } @@ -187,12 +194,16 @@ void if_delete_retain(struct interface *ifp) /* Delete and free interface structure. */ void if_delete(struct interface *ifp) { - listnode_delete(vrf_iflist(ifp->vrf_id), ifp); + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + IFNAME_RB_REMOVE(vrf, ifp); + if (ifp->ifindex != IFINDEX_INTERNAL) + IFINDEX_RB_REMOVE(vrf, ifp); if_delete_retain(ifp); - list_free(ifp->connected); - list_free(ifp->nbr_connected); + list_delete_and_null(&ifp->connected); + list_delete_and_null(&ifp->nbr_connected); if_link_params_free(ifp); @@ -202,14 +213,11 @@ void if_delete(struct interface *ifp) /* Interface existance check by index. */ struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id) { - struct listnode *node; - struct interface *ifp; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + struct interface if_tmp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { - if (ifp->ifindex == ifindex) - return ifp; - } - return NULL; + if_tmp.ifindex = ifindex; + return RB_FIND(if_index_head, &vrf->ifaces_by_index, &if_tmp); } const char *ifindex2ifname(ifindex_t ifindex, vrf_id_t vrf_id) @@ -233,15 +241,14 @@ ifindex_t ifname2ifindex(const char *name, vrf_id_t vrf_id) /* Interface existance check by interface name. */ struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id) { - struct listnode *node; - struct interface *ifp; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + struct interface if_tmp; - if (name) - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { - if (strcmp(name, ifp->name) == 0) - return ifp; - } - return NULL; + if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ) + return NULL; + + strlcpy(if_tmp.name, name, sizeof(if_tmp.name)); + return RB_FIND(if_name_head, &vrf->ifaces_by_name, &if_tmp); } struct interface *if_lookup_by_name_all_vrf(const char *name) @@ -249,6 +256,9 @@ struct interface *if_lookup_by_name_all_vrf(const char *name) struct vrf *vrf; struct interface *ifp; + if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ) + return NULL; + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { ifp = if_lookup_by_name(name, vrf->vrf_id); if (ifp) @@ -258,34 +268,17 @@ struct interface *if_lookup_by_name_all_vrf(const char *name) return NULL; } -struct interface *if_lookup_by_name_len(const char *name, size_t namelen, - vrf_id_t vrf_id) -{ - struct listnode *node; - struct interface *ifp; - - if (namelen > INTERFACE_NAMSIZ) - return NULL; - - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { - if (!memcmp(name, ifp->name, namelen) - && (ifp->name[namelen] == '\0')) - return ifp; - } - return NULL; -} - /* Lookup interface by IPv4 address. */ struct interface *if_lookup_exact_address(void *src, int family, vrf_id_t vrf_id) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct listnode *cnode; struct interface *ifp; struct prefix *p; struct connected *c; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { p = c->address; @@ -311,7 +304,7 @@ struct interface *if_lookup_exact_address(void *src, int family, struct connected *if_lookup_address(void *matchaddr, int family, vrf_id_t vrf_id) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct prefix addr; int bestlen = 0; struct listnode *cnode; @@ -331,7 +324,7 @@ struct connected *if_lookup_address(void *matchaddr, int family, match = NULL; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { if (c->address && (c->address->family == AF_INET) && prefix_match(CONNECTED_PREFIX(c), &addr) @@ -347,12 +340,12 @@ struct connected *if_lookup_address(void *matchaddr, int family, /* Lookup interface by prefix */ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct listnode *cnode; struct interface *ifp; struct connected *c; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { if (prefix_cmp(c->address, prefix) == 0) { return ifp; @@ -364,53 +357,49 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id) /* Get interface by name if given name interface doesn't exist create one. */ -struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id) +struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty) { struct interface *ifp; - return ((ifp = if_lookup_by_name(name, vrf_id)) != NULL) - ? ifp - : if_create(name, strlen(name), vrf_id); + ifp = if_lookup_by_name_all_vrf(name); + if (ifp) { + if (ifp->vrf_id == vrf_id) + return ifp; + + /* Found a match on a different VRF. If the interface command + * was entered in vty without a VRF (passed as VRF_DEFAULT), + * accept the ifp we found. If a vrf was entered and there is + * a mismatch, reject it if from vty. If it came from the kernel + * or by way of zclient, believe it and update the ifp + * accordingly. + */ + if (vty) { + if (vrf_id == VRF_DEFAULT) + return ifp; + return NULL; + } else { + if_update_to_new_vrf(ifp, vrf_id); + return ifp; + } + } + + return if_create(name, vrf_id); } -struct interface *if_get_by_name_len(const char *name, size_t namelen, - vrf_id_t vrf_id, int vty) +void if_set_index(struct interface *ifp, ifindex_t ifindex) { - struct interface *ifp; - struct vrf *vrf; - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); - ifp = if_lookup_by_name_len(name, namelen, vrf_id); - if (ifp) - return ifp; + if (ifp->ifindex == ifindex) + return; - /* Didn't find the interface on that vrf. Defined on a different one? */ - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf->vrf_id), node, ifp)) { - if (!memcmp(name, ifp->name, namelen) - && (ifp->name[namelen] == '\0')) { - /* Found a match. If the interface command was - * entered in vty without a - * VRF (passed as VRF_DEFAULT), accept the ifp - * we found. If a vrf was - * entered and there is a mismatch, reject it if - * from vty. If it came - * from the kernel by way of zclient, believe - * it and update - * the ifp accordingly. - */ - if (vty) { - if (vrf_id == VRF_DEFAULT) - return ifp; - return NULL; - } else { - if_update_to_new_vrf(ifp, vrf_id); - return ifp; - } - } - } - } - return (if_create(name, namelen, vrf_id)); + if (ifp->ifindex != IFINDEX_INTERNAL) + IFINDEX_RB_REMOVE(vrf, ifp) + + ifp->ifindex = ifindex; + + if (ifp->ifindex != IFINDEX_INTERNAL) + IFINDEX_RB_INSERT(vrf, ifp) } /* Does interface up ? */ @@ -536,13 +525,11 @@ static void if_dump(const struct interface *ifp) void if_dump_all(void) { struct vrf *vrf; - struct listnode *node; - void *p; + void *ifp; RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - if (vrf->iflist != NULL) - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, p)) - if_dump(p); + FOR_ALL_INTERFACES (vrf, ifp) + if_dump(ifp); } DEFUN (interface_desc, @@ -597,24 +584,20 @@ DEFUN (no_interface_desc, * if not: * - no idea, just get the name in its entirety. */ -static struct interface *if_sunwzebra_get(const char *name, size_t nlen, - vrf_id_t vrf_id) +static struct interface *if_sunwzebra_get(char *name, vrf_id_t vrf_id) { struct interface *ifp; - size_t seppos = 0; + char *cp; - if ((ifp = if_lookup_by_name_len(name, nlen, vrf_id)) != NULL) + if ((ifp = if_lookup_by_name(name, vrf_id)) != NULL) return ifp; /* hunt the primary interface name... */ - while (seppos < nlen && name[seppos] != ':') - seppos++; - - /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */ - if (seppos < nlen) - return if_get_by_name_len(name, seppos, vrf_id, 1); - else - return if_get_by_name_len(name, nlen, vrf_id, 1); + cp = strchr(name, ':'); + if (cp) + *cp = '\0'; + + return if_get_by_name(name, vrf_id, 1); } #endif /* SUNOS_5 */ @@ -631,10 +614,9 @@ DEFUN (interface, const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL; struct interface *ifp; - size_t sl; vrf_id_t vrf_id = VRF_DEFAULT; - if ((sl = strlen(ifname)) > INTERFACE_NAMSIZ) { + if (strlen(ifname) > INTERFACE_NAMSIZ) { vty_out(vty, "%% Interface name %s is invalid: length exceeds " "%d characters\n", @@ -648,9 +630,9 @@ DEFUN (interface, VRF_GET_ID(vrf_id, vrfname); #ifdef SUNOS_5 - ifp = if_sunwzebra_get(ifname, sl, vrf_id); + ifp = if_sunwzebra_get(ifname, vrf_id); #else - ifp = if_get_by_name_len(ifname, sl, vrf_id, 1); + ifp = if_get_by_name(ifname, vrf_id, 1); #endif /* SUNOS_5 */ if (!ifp) { @@ -697,8 +679,30 @@ DEFUN_NOSH (no_interface, return CMD_SUCCESS; } +static void if_autocomplete(vector comps, struct cmd_token *token) +{ + struct interface *ifp; + struct vrf *vrf = NULL; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + FOR_ALL_INTERFACES (vrf, ifp) { + vector_set(comps, XSTRDUP(MTYPE_COMPLETION, ifp->name)); + } + } +} + +static const struct cmd_variable_handler if_var_handlers[] = { + {/* "interface NAME" */ + .varname = "interface", + .completions = if_autocomplete}, + {.tokenname = "IFNAME", .completions = if_autocomplete}, + {.tokenname = "INTERFACE", .completions = if_autocomplete}, + {.completions = NULL}}; + void if_cmd_init(void) { + cmd_variable_handler_register(if_var_handlers); + install_element(CONFIG_NODE, &interface_cmd); install_element(CONFIG_NODE, &no_interface_cmd); @@ -718,7 +722,6 @@ DEFUN (show_address, { int idx_vrf = 3; struct listnode *node; - struct listnode *node2; struct interface *ifp; struct connected *ifc; struct prefix *p; @@ -727,9 +730,9 @@ DEFUN (show_address, if (argc > 2) VRF_GET_ID (vrf_id, argv[idx_vrf]->arg); - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) { - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc)) + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) { p = ifc->address; @@ -749,21 +752,20 @@ DEFUN (show_address_vrf_all, { struct vrf *vrf; struct listnode *node; - struct listnode *node2; struct interface *ifp; struct connected *ifc; struct prefix *p; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - if (!vrf->iflist || !listcount (vrf->iflist)) + if (RB_EMPTY (if_name_head, &vrf->ifaces_by_name)) continue; vty_out (vty, "\nVRF %u\n\n", vrf->vrf_id); - for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) { - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc)) + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) { p = ifc->address; @@ -1045,58 +1047,17 @@ ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex) } #endif /* ifaddr_ipv4_table */ -static void if_autocomplete(vector comps, struct cmd_token *token) +void if_terminate(struct vrf *vrf) { struct interface *ifp; - struct listnode *ln; - struct vrf *vrf = NULL; - - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, ln, ifp)) - vector_set(comps, XSTRDUP(MTYPE_COMPLETION, ifp->name)); - } -} - -static const struct cmd_variable_handler if_var_handlers[] = { - {/* "interface NAME" */ - .varname = "interface", - .completions = if_autocomplete}, - {.tokenname = "IFNAME", .completions = if_autocomplete}, - {.tokenname = "INTERFACE", .completions = if_autocomplete}, - {.completions = NULL}}; - -/* Initialize interface list. */ -void if_init(struct list **intf_list) -{ - *intf_list = list_new(); -#if 0 - ifaddr_ipv4_table = route_table_init (); -#endif /* ifaddr_ipv4_table */ - - (*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func; - - cmd_variable_handler_register(if_var_handlers); -} - -void if_terminate(struct list **intf_list) -{ - for (;;) { - struct interface *ifp; - - ifp = listnode_head(*intf_list); - if (ifp == NULL) - break; + while ((ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name)) != NULL) { if (ifp->node) { ifp->node->info = NULL; route_unlock_node(ifp->node); } - if_delete(ifp); } - - list_delete(*intf_list); - *intf_list = NULL; } const char *if_link_type_str(enum zebra_link_type llt) @@ -201,6 +201,8 @@ struct if_link_params { /* Interface structure */ struct interface { + RB_ENTRY(interface) name_entry, index_entry; + /* Interface name. This should probably never be changed after the interface is created, because the configuration info for this interface @@ -209,13 +211,17 @@ struct interface { To delete, just set ifindex to IFINDEX_INTERNAL to indicate that the interface does not exist in the kernel. */ - char name[INTERFACE_NAMSIZ + 1]; + char name[INTERFACE_NAMSIZ]; /* Interface index (should be IFINDEX_INTERNAL for non-kernel or - deleted interfaces). */ + deleted interfaces). + WARNING: the ifindex needs to be changed using the if_set_index() + function. Failure to respect this will cause corruption in the data + structure used to store the interfaces and if_lookup_by_index() will + not work as expected. + */ ifindex_t ifindex; #define IFINDEX_INTERNAL 0 -#define IFINDEX_DELETED INT_MAX /* Zebra internal interface status */ u_char status; @@ -282,8 +288,47 @@ struct interface { QOBJ_FIELDS }; +RB_HEAD(if_name_head, interface); +RB_PROTOTYPE(if_name_head, interface, name_entry, if_cmp_func); +RB_HEAD(if_index_head, interface); +RB_PROTOTYPE(if_index_head, interface, index_entry, if_cmp_func); DECLARE_QOBJ_TYPE(interface) +#define IFNAME_RB_INSERT(vrf, ifp) \ + if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp))) \ + zlog_err( \ + "%s(%s): corruption detected -- interface with this " \ + "name exists already in VRF %u!", \ + __func__, (ifp)->name, (ifp)->vrf_id); + +#define IFNAME_RB_REMOVE(vrf, ifp) \ + if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL) \ + zlog_err( \ + "%s(%s): corruption detected -- interface with this " \ + "name doesn't exist in VRF %u!", \ + __func__, (ifp)->name, (ifp)->vrf_id); + +#define IFINDEX_RB_INSERT(vrf, ifp) \ + if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp))) \ + zlog_err( \ + "%s(%u): corruption detected -- interface with this " \ + "ifindex exists already in VRF %u!", \ + __func__, (ifp)->ifindex, (ifp)->vrf_id); + +#define IFINDEX_RB_REMOVE(vrf, ifp) \ + if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL) \ + zlog_err( \ + "%s(%u): corruption detected -- interface with this " \ + "ifindex doesn't exist in VRF %u!", \ + __func__, (ifp)->ifindex, (ifp)->vrf_id); + +#define FOR_ALL_INTERFACES(vrf, ifp) \ + if (vrf) \ + RB_FOREACH (ifp, if_name_head, &vrf->ifaces_by_name) + +#define FOR_ALL_INTERFACES_ADDRESSES(ifp, connected, node) \ + for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) + /* called from the library code whenever interfaces are created/deleted * note: interfaces may not be fully realized at that point; also they * may not exist in the system (ifindex = IFINDEX_INTERNAL) @@ -408,8 +453,7 @@ struct nbr_connected { extern int if_cmp_name_func(char *, char *); extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id); -extern struct interface *if_create(const char *name, int namelen, - vrf_id_t vrf_id); +extern struct interface *if_create(const char *name, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id); extern struct interface *if_lookup_exact_address(void *matchaddr, int family, vrf_id_t vrf_id); @@ -422,16 +466,9 @@ extern struct interface *if_lookup_prefix(struct prefix *prefix, by a '\0' character: */ extern struct interface *if_lookup_by_name_all_vrf(const char *ifname); extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id); -extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id); - -/* For these 2 functions, the namelen argument should be the precise length - of the ifname string (not counting any optional trailing '\0' character). - In most cases, strnlen should be used to calculate the namelen value. */ -extern struct interface *if_lookup_by_name_len(const char *ifname, - size_t namelen, vrf_id_t vrf_id); -extern struct interface *if_get_by_name_len(const char *ifname, size_t namelen, - vrf_id_t vrf_id, int vty); - +extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id, + int vty); +extern void if_set_index(struct interface *ifp, ifindex_t ifindex); /* Delete the interface, but do not free the structure, and leave it in the interface list. It is often advisable to leave the pseudo interface @@ -450,9 +487,9 @@ extern int if_is_loopback(struct interface *); extern int if_is_broadcast(struct interface *); extern int if_is_pointopoint(struct interface *); extern int if_is_multicast(struct interface *); -extern void if_init(struct list **); extern void if_cmd_init(void); -extern void if_terminate(struct list **); +struct vrf; +extern void if_terminate(struct vrf *vrf); extern void if_dump_all(void); extern const char *if_flag_dump(unsigned long); extern const char *if_link_type_str(enum zebra_link_type); diff --git a/lib/keychain.c b/lib/keychain.c index f0108e0805..23a2d72b17 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -119,7 +119,7 @@ static void keychain_delete(struct keychain *keychain) if (keychain->name) XFREE(MTYPE_KEYCHAIN, keychain->name); - list_delete(keychain->key); + list_delete_and_null(&keychain->key); listnode_delete(keychain_list, keychain); keychain_free(keychain); } diff --git a/lib/libfrr.c b/lib/libfrr.c index 2859f062c1..6cb8711edf 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -768,6 +768,8 @@ void frr_vty_serv(void) static void frr_terminal_close(int isexit) { + int nullfd; + if (daemon_ctl_sock != -1) { close(daemon_ctl_sock); daemon_ctl_sock = -1; @@ -783,11 +785,16 @@ static void frr_terminal_close(int isexit) fflush(stdout); } - int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); - dup2(nullfd, 0); - dup2(nullfd, 1); - dup2(nullfd, 2); - close(nullfd); + nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); + if (nullfd == -1) { + zlog_err("%s: failed to open /dev/null: %s", __func__, + safe_strerror(errno)); + } else { + dup2(nullfd, 0); + dup2(nullfd, 1); + dup2(nullfd, 2); + close(nullfd); + } } static struct thread *daemon_ctl_thread = NULL; @@ -849,10 +856,15 @@ void frr_run(struct thread_master *master) } } else if (di->daemon_mode) { int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); - dup2(nullfd, 0); - dup2(nullfd, 1); - dup2(nullfd, 2); - close(nullfd); + if (nullfd == -1) { + zlog_err("%s: failed to open /dev/null: %s", __func__, + safe_strerror(errno)); + } else { + dup2(nullfd, 0); + dup2(nullfd, 1); + dup2(nullfd, 2); + close(nullfd); + } if (daemon_ctl_sock != -1) close(daemon_ctl_sock); diff --git a/lib/linklist.c b/lib/linklist.c index c1b056d739..2306dd6d00 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -33,7 +33,7 @@ struct list *list_new(void) } /* Free list. */ -void list_free(struct list *l) +static void list_free_internal(struct list *l) { XFREE(MTYPE_LINK_LIST, l); } @@ -239,7 +239,7 @@ void list_delete_all_node(struct list *list) assert(list); for (node = list->head; node; node = next) { next = node->next; - if (list->del) + if (*list->del) (*list->del)(node->data); listnode_free(node); } @@ -248,11 +248,17 @@ void list_delete_all_node(struct list *list) } /* Delete all listnode then free list itself. */ -void list_delete(struct list *list) +void list_delete_and_null(struct list **list) { - assert(list); - list_delete_all_node(list); - list_free(list); + assert(*list); + list_delete_all_node(*list); + list_free_internal(*list); + *list = NULL; +} + +void list_delete_original(struct list *list) +{ + list_delete_and_null(&list); } /* Lookup the node which has given data. */ diff --git a/lib/linklist.h b/lib/linklist.h index 9bd6e38499..8a43fbe64b 100644 --- a/lib/linklist.h +++ b/lib/linklist.h @@ -56,12 +56,12 @@ struct list { #define listtail(X) ((X) ? ((X)->tail) : NULL) #define listcount(X) ((X)->count) #define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL) -#define listgetdata(X) (assert((X)->data != NULL), (X)->data) +/* return X->data only if X and X->data are not NULL */ +#define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data) /* Prototypes. */ extern struct list * list_new(void); /* encouraged: set list.del callback on new lists */ -extern void list_free(struct list *); extern void listnode_add(struct list *, void *); extern void listnode_add_sort(struct list *, void *); @@ -74,7 +74,26 @@ extern void listnode_delete(struct list *, void *); extern struct listnode *listnode_lookup(struct list *, void *); extern void *listnode_head(struct list *); -extern void list_delete(struct list *); +/* + * The usage of list_delete is being transitioned to pass in + * the double pointer to remove use after free's. + * list_free usage is deprecated, it leads to memory leaks + * of the linklist nodes. Please use list_delete_and_null + * + * In Oct of 2018, rename list_delete_and_null to list_delete + * and remove list_delete_original and the list_delete #define + * Additionally remove list_free entirely + */ +#if CONFDATE > 20181001 +CPP_NOTICE("list_delete without double pointer is deprecated, please fixup") +#endif +extern void list_delete_and_null(struct list **); +extern void list_delete_original(struct list *); +#define list_delete(X) list_delete_original((X)) \ + CPP_WARN("Please transition to using list_delete_and_null") +#define list_free(X) list_delete_original((X)) \ + CPP_WARN("Please transition tousing list_delete_and_null") + extern void list_delete_all_node(struct list *); /* For ospfd and ospf6d. */ diff --git a/lib/nexthop.c b/lib/nexthop.c index ea6a310a4a..f6b2c9788d 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -128,7 +128,7 @@ int nexthop_labels_match(struct nexthop *nh1, struct nexthop *nh2) nhl1 = nh1->nh_label; nhl2 = nh2->nh_label; - if ((nhl1 && !nhl2) || (!nhl1 && nhl2)) + if (!nhl1 || !nhl2) return 0; if (nhl1->num_labels != nhl2->num_labels) diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index f50d1e2989..e881d49225 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -330,7 +330,7 @@ int ptm_lib_process_msg(ptm_lib_handle_t *hdl, int fd, char *inbuf, int inlen, char client_name[32]; int cmd_id, type, ver, msglen; csv_t *csv; - ptm_lib_msg_ctxt_t *p_ctxt; + ptm_lib_msg_ctxt_t *p_ctxt = NULL; len = _ptm_lib_read_ptm_socket(fd, inbuf, PTMLIB_MSG_HDR_LEN); if (len <= 0) diff --git a/lib/thread.c b/lib/thread.c index a69bd2f0d5..2d37857b8a 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -554,8 +554,7 @@ void thread_master_free(struct thread_master *m) { listnode_delete(masters, m); if (masters->count == 0) { - list_free(masters); - masters = NULL; + list_delete_and_null(&masters); } } pthread_mutex_unlock(&masters_mtx); @@ -570,7 +569,7 @@ void thread_master_free(struct thread_master *m) pthread_cond_destroy(&m->cancel_cond); close(m->io_pipe[0]); close(m->io_pipe[1]); - list_delete(m->cancel_req); + list_delete_and_null(&m->cancel_req); m->cancel_req = NULL; hash_clean(m->cpu_record, cpu_record_hash_free); @@ -109,7 +109,8 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name) if (vrf == NULL) { vrf = XCALLOC(MTYPE_VRF, sizeof(struct vrf)); vrf->vrf_id = VRF_UNKNOWN; - if_init(&vrf->iflist); + RB_INIT(if_name_head, &vrf->ifaces_by_name); + RB_INIT(if_index_head, &vrf->ifaces_by_index); QOBJ_REG(vrf, vrf); new = 1; @@ -153,7 +154,7 @@ void vrf_delete(struct vrf *vrf) (*vrf_master.vrf_delete_hook)(vrf); QOBJ_UNREG(vrf); - if_terminate(&vrf->iflist); + if_terminate(vrf); if (vrf->vrf_id != VRF_UNKNOWN) RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf); @@ -251,20 +252,6 @@ void *vrf_info_lookup(vrf_id_t vrf_id) return vrf ? vrf->info : NULL; } -/* Look up the interface list in a VRF. */ -struct list *vrf_iflist(vrf_id_t vrf_id) -{ - struct vrf *vrf = vrf_lookup_by_id(vrf_id); - return vrf ? vrf->iflist : NULL; -} - -/* Get the interface list of the specified VRF. Create one if not find. */ -struct list *vrf_iflist_get(vrf_id_t vrf_id) -{ - struct vrf *vrf = vrf_get(vrf_id, NULL); - return vrf->iflist; -} - /* * VRF bit-map */ @@ -77,8 +77,9 @@ struct vrf { u_char status; #define VRF_ACTIVE (1 << 0) - /* Master list of interfaces belonging to this VRF */ - struct list *iflist; + /* Interfaces belonging to this VRF */ + struct if_name_head ifaces_by_name; + struct if_index_head ifaces_by_index; /* User data */ void *info; @@ -127,15 +128,6 @@ extern void *vrf_info_get(vrf_id_t); extern void *vrf_info_lookup(vrf_id_t); /* - * Utilities to obtain the interface list - */ - -/* Look up the interface list of the specified VRF. */ -extern struct list *vrf_iflist(vrf_id_t); -/* Get the interface list of the specified VRF. Create one if not find. */ -extern struct list *vrf_iflist_get(vrf_id_t); - -/* * VRF bit-map: maintaining flags, one bit per VRF ID */ diff --git a/lib/wheel.c b/lib/wheel.c index 9f1f189b72..b1a3e89fc7 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -99,7 +99,7 @@ void wheel_delete(struct timer_wheel *wheel) int i; for (i = 0; i < wheel->slots; i++) { - list_delete(wheel->wheel_slot_lists[i]); + list_delete_and_null(&wheel->wheel_slot_lists[i]); } THREAD_OFF(wheel->timer); diff --git a/lib/workqueue.c b/lib/workqueue.c index 643ed2d2b8..952012a006 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -57,6 +57,22 @@ static void work_queue_item_free(struct work_queue_item *item) return; } +static void work_queue_item_remove(struct work_queue *wq, + struct work_queue_item *item) +{ + assert(item && item->data); + + /* call private data deletion callback if needed */ + if (wq->spec.del_item_data) + wq->spec.del_item_data(wq, item->data); + + work_queue_item_dequeue(wq, item); + + work_queue_item_free(item); + + return; +} + /* create new work queue */ struct work_queue *work_queue_new(struct thread_master *m, const char *queue_name) @@ -90,6 +106,12 @@ void work_queue_free(struct work_queue *wq) if (wq->thread != NULL) thread_cancel(wq->thread); + while (!work_queue_empty(wq)) { + struct work_queue_item *item = work_queue_last_item(wq); + + work_queue_item_remove(wq, item); + } + listnode_delete(work_queues, wq); XFREE(MTYPE_WORK_QUEUE_NAME, wq->name); @@ -137,22 +159,6 @@ void work_queue_add(struct work_queue *wq, void *data) return; } -static void work_queue_item_remove(struct work_queue *wq, - struct work_queue_item *item) -{ - assert(item && item->data); - - /* call private data deletion callback if needed */ - if (wq->spec.del_item_data) - wq->spec.del_item_data(wq, item->data); - - work_queue_item_dequeue(wq, item); - - work_queue_item_free(item); - - return; -} - static void work_queue_item_requeue(struct work_queue *wq, struct work_queue_item *item) { work_queue_item_dequeue(wq, item); diff --git a/lib/zclient.c b/lib/zclient.c index 0b06dbacba..ad5c30584c 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -123,8 +123,7 @@ void redist_del_instance(struct redist_proto *red, u_short instance) XFREE(MTYPE_REDIST_INST, id); if (!red->instances->count) { red->enabled = 0; - list_free(red->instances); - red->instances = NULL; + list_delete_and_null(&red->instances); } } @@ -1231,8 +1230,7 @@ struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id) stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); /* Lookup/create interface by name. */ - ifp = if_get_by_name_len( - ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id, 0); + ifp = if_get_by_name(ifname_tmp, vrf_id, 0); zebra_interface_if_set_value(s, ifp); @@ -1255,8 +1253,7 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id) stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); /* Lookup this by interface index. */ - ifp = if_lookup_by_name_len( - ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id); + ifp = if_lookup_by_name(ifname_tmp, vrf_id); if (ifp == NULL) { zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d", ifname_tmp, vrf_id); @@ -1334,7 +1331,7 @@ void zebra_interface_if_set_value(struct stream *s, struct interface *ifp) u_char link_params_status = 0; /* Read interface's index. */ - ifp->ifindex = stream_getl(s); + if_set_index(ifp, stream_getl(s)); ifp->status = stream_getc(s); /* Read interface's value. */ diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index a46962c91a..67e3f41b3d 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -299,7 +299,7 @@ int nhrp_interface_delete(int cmd, struct zclient *client, return 0; debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name); - ifp->ifindex = IFINDEX_INTERNAL; + if_set_index(ifp, ifp->ifindex); nhrp_interface_update(ifp); /* if_delete(ifp); */ return 0; diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index 0bada33502..6fbd6ca224 100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c @@ -352,13 +352,13 @@ int nhrp_nhs_free(struct nhrp_nhs *nhs) void nhrp_nhs_terminate(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct nhrp_interface *nifp; struct nhrp_nhs *nhs, *tmp; - struct listnode *node; afi_t afi; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { nifp = ifp->info; for (afi = 0; afi < AFI_MAX; afi++) { list_for_each_entry_safe(nhs, tmp, &nifp->afi[afi].nhslist_head, nhslist_entry) diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index bd5b1aa6f1..ab052ac04a 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -712,7 +712,7 @@ DEFUN(show_ip_nhrp, show_ip_nhrp_cmd, "Shortcut information\n" "opennhrpctl style cache dump\n") { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct info_ctx ctx = { .vty = vty, @@ -720,17 +720,17 @@ DEFUN(show_ip_nhrp, show_ip_nhrp_cmd, }; if (argc <= 3 || argv[3]->text[0] == 'c') { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx); } else if (argv[3]->text[0] == 'n') { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) nhrp_nhs_foreach(ifp, ctx.afi, show_ip_nhrp_nhs, &ctx); } else if (argv[3]->text[0] == 's') { nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx); } else { vty_out (vty, "Status: ok\n\n"); ctx.count++; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx); } @@ -796,7 +796,7 @@ DEFUN(clear_nhrp, clear_nhrp_cmd, "Dynamic cache entries\n" "Shortcut entries\n") { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct info_ctx ctx = { .vty = vty, @@ -805,7 +805,7 @@ DEFUN(clear_nhrp, clear_nhrp_cmd, }; if (argc <= 3 || argv[3]->text[0] == 'c') { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) nhrp_cache_foreach(ifp, clear_nhrp_cache, &ctx); } else { nhrp_shortcut_foreach(ctx.afi, clear_nhrp_shortcut, &ctx); @@ -843,8 +843,8 @@ static void interface_config_write_nhrp_map(struct nhrp_cache *c, void *data) static int interface_config_write(struct vty *vty) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct write_map_ctx mapctx; - struct listnode *node; struct interface *ifp; struct nhrp_interface *nifp; struct nhrp_nhs *nhs; @@ -853,7 +853,7 @@ static int interface_config_write(struct vty *vty) char buf[SU_ADDRSTRLEN]; int i; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { vty_frame(vty, "interface %s\n", ifp->name); if (ifp->desc) vty_out (vty, " description %s\n", ifp->desc); diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 36528d063c..d270b9547e 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -1110,19 +1110,21 @@ void install_element_ospf6_debug_abr(void) } struct ospf6_lsa_handler inter_prefix_handler = { - OSPF6_LSTYPE_INTER_PREFIX, - "Inter-Prefix", - "IAP", - ospf6_inter_area_prefix_lsa_show, - ospf6_inter_area_prefix_lsa_get_prefix_str, + .lh_type = OSPF6_LSTYPE_INTER_PREFIX, + .lh_name = "Inter-Prefix", + .lh_short_name = "IAP", + .lh_show = ospf6_inter_area_prefix_lsa_show, + .lh_get_prefix_str = ospf6_inter_area_prefix_lsa_get_prefix_str, + .lh_debug = 0 }; struct ospf6_lsa_handler inter_router_handler = { - OSPF6_LSTYPE_INTER_ROUTER, - "Inter-Router", - "IAR", - ospf6_inter_area_router_lsa_show, - ospf6_inter_area_router_lsa_get_prefix_str, + .lh_type = OSPF6_LSTYPE_INTER_ROUTER, + .lh_name = "Inter-Router", + .lh_short_name = "IAR", + .lh_show = ospf6_inter_area_router_lsa_show, + .lh_get_prefix_str = ospf6_inter_area_router_lsa_get_prefix_str, + .lh_debug = 0 }; void ospf6_abr_init(void) diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index b5584dc86d..b126786246 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -272,7 +272,7 @@ void ospf6_area_delete(struct ospf6_area *oa) for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi)) oi->area = NULL; - list_delete(oa->if_list); + list_delete_and_null(&oa->if_list); ospf6_lsdb_delete(oa->lsdb); ospf6_lsdb_delete(oa->lsdb_self); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index de20fbc3ab..c65578c11e 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -438,6 +438,9 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, if (!ospf6_zebra_is_redistribute(type)) return; + memset(&troute, 0, sizeof(troute)); + memset(&tinfo, 0, sizeof(tinfo)); + if (IS_OSPF6_DEBUG_ASBR) { prefix2str(prefix, pbuf, sizeof(pbuf)); zlog_debug("Redistribute %s (%s)", pbuf, ZROUTE_NAME(type)); @@ -457,8 +460,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, /* apply route-map */ if (ospf6->rmap[type].map) { - memset(&troute, 0, sizeof(troute)); - memset(&tinfo, 0, sizeof(tinfo)); troute.route_option = &tinfo; tinfo.ifindex = ifindex; tinfo.tag = tag; @@ -1234,8 +1235,13 @@ DEFUN (show_ipv6_ospf6_redistribute, } struct ospf6_lsa_handler as_external_handler = { - OSPF6_LSTYPE_AS_EXTERNAL, "AS-External", "ASE", - ospf6_as_external_lsa_show, ospf6_as_external_lsa_get_prefix_str}; + .lh_type = OSPF6_LSTYPE_AS_EXTERNAL, + .lh_name = "AS-External", + .lh_short_name = "ASE", + .lh_show = ospf6_as_external_lsa_show, + .lh_get_prefix_str = ospf6_as_external_lsa_get_prefix_str, + .lh_debug = 0 +}; void ospf6_asbr_init(void) { diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index fa0030b6d9..e28af9d06d 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -141,7 +141,8 @@ static void ospf6_bfd_reg_dereg_all_nbr(struct ospf6_interface *oi, int command) static int ospf6_bfd_nbr_replay(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { - struct listnode *inode, *nnode; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct listnode *node; struct interface *ifp; struct ospf6_interface *oi; struct ospf6_neighbor *on; @@ -154,13 +155,13 @@ static int ospf6_bfd_nbr_replay(int command, struct zclient *zclient, bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); /* Replay the neighbor, if BFD is enabled on the interface*/ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), inode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { oi = (struct ospf6_interface *)ifp->info; if (!oi || !oi->bfd_info) continue; - for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, nnode, on)) { + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) { if (on->state < OSPF6_NEIGHBOR_TWOWAY) continue; diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 8e01cb4379..f237e4bef3 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -242,7 +242,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi) for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) ospf6_neighbor_delete(on); - list_delete(oi->neighbor_list); + list_delete_and_null(&oi->neighbor_list); THREAD_OFF(oi->thread_send_hello); THREAD_OFF(oi->thread_send_lsupdate); @@ -983,9 +983,9 @@ DEFUN (show_ipv6_ospf6_interface, INTERFACE_STR IFNAME_STR) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int idx_ifname = 4; struct interface *ifp; - struct listnode *i; if (argc == 5) { ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); @@ -996,7 +996,7 @@ DEFUN (show_ipv6_ospf6_interface, } ospf6_interface_show(vty, ifp); } else { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ospf6_interface_show(vty, ifp); } @@ -1054,12 +1054,12 @@ DEFUN (show_ipv6_ospf6_interface_prefix, OSPF6_ROUTE_MATCH_STR "Display details of the prefixes\n") { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int idx_prefix = 5; - struct listnode *i; struct ospf6_interface *oi; struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { oi = (struct ospf6_interface *)ifp->info; if (oi == NULL) continue; @@ -1755,11 +1755,11 @@ DEFUN (no_ipv6_ospf6_network, static int config_write_ospf6_interface(struct vty *vty) { - struct listnode *i; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct ospf6_interface *oi; struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { oi = (struct ospf6_interface *)ifp->info; if (oi == NULL) continue; @@ -1905,13 +1905,13 @@ DEFUN (clear_ipv6_ospf6_interface, IFNAME_STR ) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int idx_ifname = 4; struct interface *ifp; - struct listnode *node; if (argc == 4) /* Clear all the ospfv3 interfaces. */ { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ospf6_interface_clear(vty, ifp); } else /* Interface name is specified. */ { diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index e4644bb09f..a2caeccb86 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -1630,21 +1630,41 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa) oa->name); } -struct ospf6_lsa_handler router_handler = {OSPF6_LSTYPE_ROUTER, "Router", "Rtr", - ospf6_router_lsa_show, - ospf6_router_lsa_get_nbr_id}; - -struct ospf6_lsa_handler network_handler = {OSPF6_LSTYPE_NETWORK, "Network", - "Net", ospf6_network_lsa_show, - ospf6_network_lsa_get_ar_id}; - -struct ospf6_lsa_handler link_handler = {OSPF6_LSTYPE_LINK, "Link", "Lnk", - ospf6_link_lsa_show, - ospf6_link_lsa_get_prefix_str}; +struct ospf6_lsa_handler router_handler = { + .lh_type = OSPF6_LSTYPE_ROUTER, + .lh_name = "Router", + .lh_short_name = "Rtr", + .lh_show = ospf6_router_lsa_show, + .lh_get_prefix_str = ospf6_router_lsa_get_nbr_id, + .lh_debug = 0 +}; + +struct ospf6_lsa_handler network_handler = { + .lh_type = OSPF6_LSTYPE_NETWORK, + .lh_name = "Network", + .lh_short_name = "Net", + .lh_show = ospf6_network_lsa_show, + .lh_get_prefix_str = ospf6_network_lsa_get_ar_id, + .lh_debug = 0 +}; + +struct ospf6_lsa_handler link_handler = { + .lh_type = OSPF6_LSTYPE_LINK, + .lh_name = "Link", + .lh_short_name = "Lnk", + .lh_show = ospf6_link_lsa_show, + .lh_get_prefix_str = ospf6_link_lsa_get_prefix_str, + .lh_debug = 0 +}; struct ospf6_lsa_handler intra_prefix_handler = { - OSPF6_LSTYPE_INTRA_PREFIX, "Intra-Prefix", "INP", - ospf6_intra_prefix_lsa_show, ospf6_intra_prefix_lsa_get_prefix_str}; + .lh_type = OSPF6_LSTYPE_INTRA_PREFIX, + .lh_name = "Intra-Prefix", + .lh_short_name = "INP", + .lh_show = ospf6_intra_prefix_lsa_show, + .lh_get_prefix_str = ospf6_intra_prefix_lsa_get_prefix_str, + .lh_debug = 0 +}; void ospf6_intra_init(void) { diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index a0dad9344a..82f75b153e 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -68,19 +68,25 @@ static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) return 0; } -struct ospf6_lsa_handler unknown_handler = { - OSPF6_LSTYPE_UNKNOWN, "Unknown", "Unk", ospf6_unknown_lsa_show, NULL}; +static struct ospf6_lsa_handler unknown_handler = { + .lh_type = OSPF6_LSTYPE_UNKNOWN, + .lh_name = "Unknown", + .lh_short_name = "Unk", + .lh_show = ospf6_unknown_lsa_show, + .lh_get_prefix_str = NULL, + .lh_debug = 0 /* No default debug */ +}; -void ospf6_install_lsa_handler(struct ospf6_lsa_handler *handler) +void ospf6_install_lsa_handler(const struct ospf6_lsa_handler *handler) { /* type in handler is host byte order */ - int index = handler->type & OSPF6_LSTYPE_FCODE_MASK; - vector_set_index(ospf6_lsa_handler_vector, index, handler); + int index = handler->lh_type & OSPF6_LSTYPE_FCODE_MASK; + vector_set_index(ospf6_lsa_handler_vector, index, (void *)handler); } -struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type) +const struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type) { - struct ospf6_lsa_handler *handler = NULL; + const struct ospf6_lsa_handler *handler = NULL; unsigned int index = ntohs(type) & OSPF6_LSTYPE_FCODE_MASK; if (index >= vector_active(ospf6_lsa_handler_vector)) @@ -97,11 +103,11 @@ struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type) const char *ospf6_lstype_name(u_int16_t type) { static char buf[8]; - struct ospf6_lsa_handler *handler; + const struct ospf6_lsa_handler *handler; handler = ospf6_get_lsa_handler(type); if (handler && handler != &unknown_handler) - return handler->name; + return handler->lh_name; snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type)); return buf; @@ -110,11 +116,11 @@ const char *ospf6_lstype_name(u_int16_t type) const char *ospf6_lstype_short_name(u_int16_t type) { static char buf[8]; - struct ospf6_lsa_handler *handler; + const struct ospf6_lsa_handler *handler; handler = ospf6_get_lsa_handler(type); if (handler && handler != &unknown_handler) - return handler->short_name; + return handler->lh_short_name; snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type)); return buf; @@ -122,7 +128,7 @@ const char *ospf6_lstype_short_name(u_int16_t type) u_char ospf6_lstype_debug(u_int16_t type) { - struct ospf6_lsa_handler *handler; + const struct ospf6_lsa_handler *handler; handler = ospf6_get_lsa_handler(type); return handler->debug; } @@ -369,7 +375,7 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa) { char adv_router[16], id[16]; int type; - struct ospf6_lsa_handler *handler; + const struct ospf6_lsa_handler *handler; char buf[64], tmpbuf[80]; int cnt = 0; @@ -389,14 +395,14 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa) ospf6_lstype_short_name(lsa->header->type), id, adv_router, ospf6_lsa_age_current(lsa), (u_long)ntohl(lsa->header->seqnum), - handler->get_prefix_str(lsa, buf, sizeof(buf), 0)); + handler->lh_get_prefix_str(lsa, buf, sizeof(buf), 0)); } else if (type != OSPF6_LSTYPE_UNKNOWN) { sprintf(tmpbuf, "%-4s %-15s%-15s%4hu %8lx", ospf6_lstype_short_name(lsa->header->type), id, adv_router, ospf6_lsa_age_current(lsa), (u_long)ntohl(lsa->header->seqnum)); - while (handler->get_prefix_str(lsa, buf, sizeof(buf), cnt) + while (handler->lh_get_prefix_str(lsa, buf, sizeof(buf), cnt) != NULL) { vty_out(vty, "%s %30s\n", tmpbuf, buf); cnt++; @@ -465,7 +471,7 @@ void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa) void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { char adv_router[64], id[64]; - struct ospf6_lsa_handler *handler; + const struct ospf6_lsa_handler *handler; struct timeval now, res; char duration[64]; @@ -490,9 +496,13 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) vty_out(vty, "Duration: %s\n", duration); handler = ospf6_get_lsa_handler(lsa->header->type); - if (handler->show == NULL) - handler = &unknown_handler; - (*handler->show)(vty, lsa); + + if (handler->lh_show != NULL) + handler->lh_show(vty, lsa); + else { + assert(unknown_handler.lh_show != NULL); + unknown_handler.lh_show(vty, lsa); + } vty_out(vty, "\n"); } @@ -739,22 +749,22 @@ void ospf6_lsa_terminate(void) vector_free(ospf6_lsa_handler_vector); } -static char *ospf6_lsa_handler_name(struct ospf6_lsa_handler *h) +static char *ospf6_lsa_handler_name(const struct ospf6_lsa_handler *h) { static char buf[64]; unsigned int i; - unsigned int size = strlen(h->name); + unsigned int size = strlen(h->lh_name); - if (!strcmp(h->name, "unknown") && h->type != OSPF6_LSTYPE_UNKNOWN) { - snprintf(buf, sizeof(buf), "%#04hx", h->type); + if (!strcmp(h->lh_name, "unknown") && h->lh_type != OSPF6_LSTYPE_UNKNOWN) { + snprintf(buf, sizeof(buf), "%#04hx", h->lh_type); return buf; } for (i = 0; i < MIN(size, sizeof(buf)); i++) { - if (!islower((unsigned char)h->name[i])) - buf[i] = tolower((unsigned char)h->name[i]); + if (!islower((unsigned char)h->lh_name[i])) + buf[i] = tolower((unsigned char)h->lh_name[i]); else - buf[i] = h->name[i]; + buf[i] = h->lh_name[i]; } buf[size] = '\0'; return buf; @@ -791,7 +801,7 @@ DEFUN (debug_ospf6_lsa_type, strlen(argv[idx_lsa]->arg)) == 0) break; - if (!strcasecmp(argv[idx_lsa]->arg, handler->name)) + if (!strcasecmp(argv[idx_lsa]->arg, handler->lh_name)) break; handler = NULL; } @@ -844,7 +854,7 @@ DEFUN (no_debug_ospf6_lsa_type, strlen(argv[idx_lsa]->arg)) == 0) break; - if (!strcasecmp(argv[idx_lsa]->arg, handler->name)) + if (!strcasecmp(argv[idx_lsa]->arg, handler->lh_name)) break; } @@ -875,7 +885,7 @@ void install_element_ospf6_debug_lsa(void) int config_write_ospf6_debug_lsa(struct vty *vty) { u_int i; - struct ospf6_lsa_handler *handler; + const struct ospf6_lsa_handler *handler; for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) { handler = vector_slot(ospf6_lsa_handler_vector, i); diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index ef63429fdf..3536d33d19 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -137,18 +137,25 @@ struct ospf6_lsa { #define OSPF6_LSA_SEQWRAPPED 0x20 struct ospf6_lsa_handler { - u_int16_t type; /* host byte order */ - const char *name; - const char *short_name; - int (*show)(struct vty *, struct ospf6_lsa *); - char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, int buflen, - int pos); + const struct { + u_int16_t type; /* host byte order */ + const char *name; + const char *short_name; + int (*show)(struct vty *, struct ospf6_lsa *); + char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, int buflen, + int pos); + } s; +#define lh_type s.type +#define lh_name s.name +#define lh_short_name s.short_name +#define lh_show s.show +#define lh_get_prefix_str s.get_prefix_str u_char debug; +#define lh_debug debug }; -extern struct ospf6_lsa_handler unknown_handler; -#define OSPF6_LSA_IS_KNOWN(type) \ - (ospf6_get_lsa_handler(type) != &unknown_handler ? 1 : 0) +#define OSPF6_LSA_IS_KNOWN(t) \ + (ospf6_get_lsa_handler(t)->lh_type != OSPF6_LSTYPE_UNKNOWN ? 1 : 0) extern vector ospf6_lsa_handler_vector; @@ -237,8 +244,8 @@ extern int ospf6_lsa_checksum_valid(struct ospf6_lsa_header *); extern int ospf6_lsa_prohibited_duration(u_int16_t type, u_int32_t id, u_int32_t adv_router, void *scope); -extern void ospf6_install_lsa_handler(struct ospf6_lsa_handler *handler); -extern struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type); +extern void ospf6_install_lsa_handler(const struct ospf6_lsa_handler *handler); +extern const struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type); extern void ospf6_lsa_init(void); extern void ospf6_lsa_terminate(void); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index e582737f94..9a6729ee2a 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -79,7 +79,7 @@ struct thread_master *master; static void __attribute__((noreturn)) ospf6_exit(int status) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; frr_early_fini(); @@ -89,7 +89,7 @@ static void __attribute__((noreturn)) ospf6_exit(int status) bfd_gbl_exit(); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) if (ifp->info != NULL) ospf6_interface_delete(ifp->info); @@ -125,7 +125,6 @@ static void sigint(void) static void sigterm(void) { zlog_notice("Terminating on signal SIGTERM"); - ospf6_clean(); ospf6_exit(0); } diff --git a/ospf6d/ospf6_proto.h b/ospf6d/ospf6_proto.h index 174b5a4f0f..5919190854 100644 --- a/ospf6d/ospf6_proto.h +++ b/ospf6d/ospf6_proto.h @@ -62,6 +62,7 @@ struct ospf6_prefix { #define prefix_metric u._prefix_metric #define prefix_refer_lstype u._prefix_referenced_lstype /* followed by one address_prefix */ + struct in6_addr addr[]; }; #define OSPF6_PREFIX_OPTION_NU (1 << 0) /* No Unicast */ diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index e58eab2b15..3c77c483ea 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -353,7 +353,7 @@ void ospf6_route_delete(struct ospf6_route *route) { if (route) { if (route->nh_list) - list_delete(route->nh_list); + list_delete_and_null(&route->nh_list); XFREE(MTYPE_OSPF6_ROUTE, route); } } @@ -683,9 +683,9 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, /* Else, this is the brand new route regarding to the prefix */ if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) - zlog_debug("%s %p: route add %p: brand new route", + zlog_debug("%s %p: route add %p %s : brand new route", ospf6_route_table_name(table), (void *)table, - (void *)route); + (void *)route, buf); else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) zlog_debug("%s: route add: brand new route", ospf6_route_table_name(table)); @@ -760,9 +760,9 @@ void ospf6_route_remove(struct ospf6_route *route, prefix2str(&route->prefix, buf, sizeof(buf)); if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) - zlog_debug("%s %p: route remove %p: %s rnode refcount %u", + zlog_debug("%s %p: route remove %p: %s refcount %u", ospf6_route_table_name(table), (void *)table, - (void *)route, buf, route->rnode->lock); + (void *)route, buf, route->lock); else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) zlog_debug("%s: route remove: %s", ospf6_route_table_name(table), buf); @@ -801,6 +801,7 @@ void ospf6_route_remove(struct ospf6_route *route, SET_FLAG(route->flag, OSPF6_ROUTE_WAS_REMOVED); + /* Note hook_remove may call ospf6_route_remove */ if (table->hook_remove) (*table->hook_remove)(route); @@ -1469,13 +1470,13 @@ DEFUN (debug_ospf6_route, int idx_type = 3; unsigned char level = 0; - if (!strncmp(argv[idx_type]->arg, "table", 5)) + if (!strcmp(argv[idx_type]->text, "table")) level = OSPF6_DEBUG_ROUTE_TABLE; - else if (!strncmp(argv[idx_type]->arg, "intra", 5)) + else if (!strcmp(argv[idx_type]->text, "intra-area")) level = OSPF6_DEBUG_ROUTE_INTRA; - else if (!strncmp(argv[idx_type]->arg, "inter", 5)) + else if (!strcmp(argv[idx_type]->text, "inter-area")) level = OSPF6_DEBUG_ROUTE_INTER; - else if (!strncmp(argv[idx_type]->arg, "memor", 5)) + else if (!strcmp(argv[idx_type]->text, "memory")) level = OSPF6_DEBUG_ROUTE_MEMORY; OSPF6_DEBUG_ROUTE_ON(level); return CMD_SUCCESS; @@ -1496,13 +1497,13 @@ DEFUN (no_debug_ospf6_route, int idx_type = 4; unsigned char level = 0; - if (!strncmp(argv[idx_type]->arg, "table", 5)) + if (!strcmp(argv[idx_type]->text, "table")) level = OSPF6_DEBUG_ROUTE_TABLE; - else if (!strncmp(argv[idx_type]->arg, "intra", 5)) + else if (!strcmp(argv[idx_type]->text, "intra-area")) level = OSPF6_DEBUG_ROUTE_INTRA; - else if (!strncmp(argv[idx_type]->arg, "inter", 5)) + else if (!strcmp(argv[idx_type]->text, "inter-area")) level = OSPF6_DEBUG_ROUTE_INTER; - else if (!strncmp(argv[idx_type]->arg, "memor", 5)) + else if (!strcmp(argv[idx_type]->text, "memory")) level = OSPF6_DEBUG_ROUTE_MEMORY; OSPF6_DEBUG_ROUTE_OFF(level); return CMD_SUCCESS; @@ -1516,6 +1517,9 @@ int config_write_ospf6_debug_route(struct vty *vty) vty_out(vty, "debug ospf6 route intra-area\n"); if (IS_OSPF6_DEBUG_ROUTE(INTER)) vty_out(vty, "debug ospf6 route inter-area\n"); + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + vty_out(vty, "debug ospf6 route memory\n"); + return 0; } diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 0b399bad10..c148107449 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -837,6 +837,7 @@ static u_char *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct ospf6_lsa *lsa = NULL; ifindex_t ifindex; uint32_t area_id, id, instid, adv_router; @@ -955,8 +956,7 @@ static u_char *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length, if (!ifslist) return NULL; ifslist->cmp = (int (*)(void *, void *))if_icmp_func; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, - iif)) + FOR_ALL_INTERFACES (vrf, iif) listnode_add_sort(ifslist, iif); for (ALL_LIST_ELEMENTS_RO(ifslist, node, iif)) { @@ -1042,6 +1042,7 @@ static u_char *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); ifindex_t ifindex = 0; unsigned int instid = 0; struct ospf6_interface *oi = NULL; @@ -1092,7 +1093,7 @@ static u_char *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, if (!ifslist) return NULL; ifslist->cmp = (int (*)(void *, void *))if_icmp_func; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, iif)) + FOR_ALL_INTERFACES (vrf, iif) listnode_add_sort(ifslist, iif); for (ALL_LIST_ELEMENTS_RO(ifslist, i, iif)) { @@ -1194,6 +1195,7 @@ static u_char *ospfv3NbrEntry(struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); ifindex_t ifindex = 0; unsigned int instid, rtrid; struct ospf6_interface *oi = NULL; @@ -1253,7 +1255,7 @@ static u_char *ospfv3NbrEntry(struct variable *v, oid *name, size_t *length, if (!ifslist) return NULL; ifslist->cmp = (int (*)(void *, void *))if_icmp_func; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, iif)) + FOR_ALL_INTERFACES (vrf, iif) listnode_add_sort(ifslist, iif); for (ALL_LIST_ELEMENTS_RO(ifslist, i, iif)) { diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index ccfa25aaa8..2381318b27 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -152,8 +152,8 @@ static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa) static void ospf6_vertex_delete(struct ospf6_vertex *v) { - list_delete(v->nh_list); - list_delete(v->child_list); + list_delete_and_null(&v->nh_list); + list_delete_and_null(&v->child_list); XFREE(MTYPE_OSPF6_VERTEX, v); } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 9794e92b06..e0844765d3 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -172,7 +172,7 @@ void ospf6_delete(struct ospf6 *o) ospf6_area_delete(oa); - list_delete(o->area_list); + list_delete_and_null(&o->area_list); ospf6_lsdb_delete(o->lsdb); ospf6_lsdb_delete(o->lsdb_self); @@ -595,7 +595,7 @@ DEFUN (ospf6_interface_area, u_int32_t area_id; /* find/create ospf6 interface */ - ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); + ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT, 0); oi = (struct ospf6_interface *)ifp->info; if (oi == NULL) oi = ospf6_interface_create(ifp); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 30bb4393c7..b032bd7a79 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -126,7 +126,7 @@ static int ospf6_zebra_if_del(int command, struct zclient *zclient, ospf6_interface_if_del (ifp); #endif /*0*/ - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 252a5df0fd..8c1ad5ff0c 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -180,7 +180,7 @@ void ospf_apiserver_term(void) /* Free client list itself */ if (apiserver_list) - list_delete(apiserver_list); + list_delete_and_null(&apiserver_list); /* Free wildcard list */ /* XXX */ @@ -2322,7 +2322,7 @@ void ospf_apiserver_clients_notify_nsm_change(struct ospf_neighbor *nbr) { struct msg *msg; struct in_addr ifaddr = {.s_addr = 0L}; - struct in_addr nbraddr = {.s_addr = 0L}; + struct in_addr nbraddr; assert(nbr); diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 877e4b7fb0..2f1b27f0f1 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -77,7 +77,7 @@ struct ospf_route *ospf_find_asbr_route(struct ospf *ospf, /* If none is found -- look through all. */ if (listcount(chosen) == 0) { - list_free(chosen); + list_delete_and_null(&chosen); chosen = rn->info; } @@ -98,7 +98,7 @@ struct ospf_route *ospf_find_asbr_route(struct ospf *ospf, } if (chosen != rn->info) - list_delete(chosen); + list_delete_and_null(&chosen); return best; } @@ -761,7 +761,7 @@ void ospf_ase_external_lsas_finish(struct route_table *rt) if ((lst = rn->info) != NULL) { for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) ospf_lsa_unlock(&lsa); /* external_lsas lst */ - list_delete(lst); + list_delete_and_null(&lst); } route_table_finish(rt); diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index eca0f85f57..5933f5abfe 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -169,6 +169,7 @@ const char *ospf_timeval_dump(struct timeval *t, char *buf, size_t size) if (us >= 1000) { ms = us / 1000; us %= 1000; + (void)us; /* unused */ } if (ms >= 1000) { diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index d8d7caa688..34a1e6f6d6 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -313,10 +313,10 @@ void ospf_if_free(struct ospf_interface *oi) route_table_finish(oi->ls_upd_queue); /* Free any lists that should be freed */ - list_free(oi->nbr_nbma); + list_delete_and_null(&oi->nbr_nbma); - list_free(oi->ls_ack); - list_free(oi->ls_ack_direct.ls_ack); + list_delete_and_null(&oi->ls_ack); + list_delete_and_null(&oi->ls_ack_direct.ls_ack); if (IS_DEBUG_OSPF_EVENT) zlog_debug("%s: ospf interface %s vrf %s id %u deleted", @@ -509,7 +509,7 @@ static struct ospf_if_params *ospf_new_if_params(void) void ospf_del_if_params(struct ospf_if_params *oip) { - list_delete(oip->auth_crypt); + list_delete_and_null(&oip->auth_crypt); bfd_info_free(&(oip->bfd_info)); XFREE(MTYPE_OSPF_IF_PARAMS, oip); } @@ -798,7 +798,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf, { struct ospf_interface *voi; struct interface *vi; - char ifname[INTERFACE_NAMSIZ + 1]; + char ifname[INTERFACE_NAMSIZ]; struct ospf_area *area; struct in_addr area_id; struct connected *co; @@ -819,7 +819,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf, ospf->vrf_id); snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count); - vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id); + vi = if_create(ifname, ospf->vrf_id); /* * if_create sets ZEBRA_INTERFACE_LINKDETECTION * virtual links don't need this. diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index f223a870da..25ab9cbe0f 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -104,7 +104,7 @@ static struct ospf_neighbor *ospf_elect_dr(struct ospf_interface *oi, else DR(oi).s_addr = 0; - list_delete(dr_list); + list_delete_and_null(&dr_list); return dr; } @@ -144,8 +144,8 @@ static struct ospf_neighbor *ospf_elect_bdr(struct ospf_interface *oi, else BDR(oi).s_addr = 0; - list_delete(bdr_list); - list_delete(no_dr_list); + list_delete_and_null(&bdr_list); + list_delete_and_null(&no_dr_list); return bdr; } @@ -232,7 +232,7 @@ static int ospf_dr_election(struct ospf_interface *oi) zlog_debug("DR-Election[2nd]: DR %s", inet_ntoa(DR(oi))); } - list_delete(el_list); + list_delete_and_null(&el_list); /* if DR or BDR changes, cause AdjOK? neighbor event. */ if (!IPV4_ADDR_SAME(&old_dr, &DR(oi)) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index e5d4d34231..74d5178f55 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -1702,7 +1702,7 @@ static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa, not adversited into OSPF as an internal OSPF route and the type-7 LSA's P-bit is set a forwarding address should be - selected from one of the router's active OSPF inteface + selected from one of the router's active OSPF interface addresses which belong to the NSSA. If no such addresses exist, then @@ -3622,7 +3622,7 @@ void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa) ospf->lsa_refresh_queue.qs[lsa->refresh_list]; listnode_delete(refresh_list, lsa); if (!listcount(refresh_list)) { - list_free(refresh_list); + list_delete_and_null(&refresh_list); ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL; } ospf_lsa_unlock(&lsa); /* lsa_refresh_queue */ @@ -3691,7 +3691,7 @@ int ospf_lsa_refresh_walker(struct thread *t) lsa->refresh_list = -1; listnode_add(lsa_to_refresh, lsa); } - list_free(refresh_list); + list_delete_and_null(&refresh_list); } } @@ -3707,7 +3707,7 @@ int ospf_lsa_refresh_walker(struct thread *t) &lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/ } - list_delete(lsa_to_refresh); + list_delete_and_null(&lsa_to_refresh); if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) zlog_debug("LSA[Refresh]: ospf_lsa_refresh_walker(): end"); diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index d1c1429054..699f2341d5 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -220,8 +220,10 @@ int ospf_sock_init(struct ospf *ospf) } ret = ospf_bind_vrfdevice(ospf, ospf_sock); - if (ret < 0) + if (ret < 0) { + close(ospf_sock); goto out; + } #ifdef IP_HDRINCL /* we will include IP header with packet */ @@ -232,6 +234,7 @@ int ospf_sock_init(struct ospf *ospf) zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", ospf_sock, safe_strerror(save_errno)); + close(ospf_sock); goto out; } #elif defined(IPTOS_PREC_INTERNETCONTROL) diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index bc71e371b1..5a1f28b036 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -113,7 +113,7 @@ void ospf_opaque_term(void) int ospf_opaque_type9_lsa_init(struct ospf_interface *oi) { if (oi->opaque_lsa_self != NULL) - list_delete(oi->opaque_lsa_self); + list_delete_and_null(&oi->opaque_lsa_self); oi->opaque_lsa_self = list_new(); oi->opaque_lsa_self->del = free_opaque_info_per_type; @@ -125,7 +125,7 @@ void ospf_opaque_type9_lsa_term(struct ospf_interface *oi) { OSPF_TIMER_OFF(oi->t_opaque_lsa_self); if (oi->opaque_lsa_self != NULL) - list_delete(oi->opaque_lsa_self); + list_delete_and_null(&oi->opaque_lsa_self); oi->opaque_lsa_self = NULL; return; } @@ -133,7 +133,7 @@ void ospf_opaque_type9_lsa_term(struct ospf_interface *oi) int ospf_opaque_type10_lsa_init(struct ospf_area *area) { if (area->opaque_lsa_self != NULL) - list_delete(area->opaque_lsa_self); + list_delete_and_null(&area->opaque_lsa_self); area->opaque_lsa_self = list_new(); area->opaque_lsa_self->del = free_opaque_info_per_type; @@ -154,15 +154,14 @@ void ospf_opaque_type10_lsa_term(struct ospf_area *area) OSPF_TIMER_OFF(area->t_opaque_lsa_self); if (area->opaque_lsa_self != NULL) - list_delete(area->opaque_lsa_self); - area->opaque_lsa_self = NULL; + list_delete_and_null(&area->opaque_lsa_self); return; } int ospf_opaque_type11_lsa_init(struct ospf *top) { if (top->opaque_lsa_self != NULL) - list_delete(top->opaque_lsa_self); + list_delete_and_null(&top->opaque_lsa_self); top->opaque_lsa_self = list_new(); top->opaque_lsa_self->del = free_opaque_info_per_type; @@ -183,8 +182,7 @@ void ospf_opaque_type11_lsa_term(struct ospf *top) OSPF_TIMER_OFF(top->t_opaque_lsa_self); if (top->opaque_lsa_self != NULL) - list_delete(top->opaque_lsa_self); - top->opaque_lsa_self = NULL; + list_delete_and_null(&top->opaque_lsa_self); return; } @@ -287,16 +285,16 @@ static void ospf_opaque_funclist_term(void) struct list *funclist; funclist = ospf_opaque_wildcard_funclist; - list_delete(funclist); + list_delete_and_null(&funclist); funclist = ospf_opaque_type9_funclist; - list_delete(funclist); + list_delete_and_null(&funclist); funclist = ospf_opaque_type10_funclist; - list_delete(funclist); + list_delete_and_null(&funclist); funclist = ospf_opaque_type11_funclist; - list_delete(funclist); + list_delete_and_null(&funclist); return; } @@ -616,7 +614,7 @@ static void free_opaque_info_per_type(void *val) } OSPF_TIMER_OFF(oipt->t_opaque_lsa_self); - list_delete(oipt->id_list); + list_delete_and_null(&oipt->id_list); XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt); return; } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 015eac096c..47f5ee76d2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -519,7 +519,7 @@ int ospf_ls_upd_timer(struct thread *thread) if (listcount(update) > 0) ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT); - list_delete(update); + list_delete_and_null(&update); } /* Set LS Update retransmission timer. */ @@ -1572,7 +1572,7 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, /* Verify LSA type. */ if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); return; } @@ -1581,7 +1581,7 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, adv_router); if (find == NULL) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); return; } @@ -1615,9 +1615,9 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); } else - list_free(ls_upd); + list_delete_and_null(&ls_upd); } /* Get the list of LSAs from Link State Update packet. @@ -1758,7 +1758,7 @@ static void ospf_upd_list_clean(struct list *lsas) for (ALL_LIST_ELEMENTS(lsas, node, nnode, lsa)) ospf_lsa_discard(lsa); - list_delete(lsas); + list_delete_and_null(&lsas); } /* OSPF Link State Update message read -- RFC2328 Section 13. */ @@ -2159,7 +2159,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, #undef DISCARD_LSA assert(listcount(lsas) == 0); - list_delete(lsas); + list_delete_and_null(&lsas); } /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */ @@ -3774,7 +3774,7 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa, listnode_add(update, lsa); ospf_ls_upd_send(nbr, update, flag); - list_delete(update); + list_delete_and_null(&update); } /* Determine size for packet. Must be at least big enough to accomodate next @@ -3918,8 +3918,7 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread) /* list might not be empty. */ if (listcount(update) == 0) { - list_delete(rn->info); - rn->info = NULL; + list_delete_and_null((struct list **)&rn->info); route_unlock_node(rn); } else again = 1; diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index f9e346b1d1..69f6883186 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -188,11 +188,9 @@ static int ospf_router_info_unregister() void ospf_router_info_term(void) { - list_delete(OspfRI.pce_info.pce_domain); - list_delete(OspfRI.pce_info.pce_neighbor); + list_delete_and_null(&OspfRI.pce_info.pce_domain); + list_delete_and_null(&OspfRI.pce_info.pce_neighbor); - OspfRI.pce_info.pce_domain = NULL; - OspfRI.pce_info.pce_neighbor = NULL; OspfRI.enabled = false; ospf_router_info_unregister(); @@ -661,6 +659,7 @@ static int ospf_router_info_lsa_originate1(void *arg) if (top == NULL) { zlog_debug("%s: ospf instance not found for vrf id %u", __PRETTY_FUNCTION__, vrf_id); + ospf_lsa_unlock(&new); return rc; } diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index ca851ec75d..cc7c6d2666 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -54,7 +54,7 @@ struct ospf_route *ospf_route_new() void ospf_route_free(struct ospf_route * or) { if (or->paths) - list_delete(or->paths); + list_delete_and_null(&or->paths); XFREE(MTYPE_OSPF_ROUTE, or); } @@ -902,7 +902,7 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs) zlog_debug("Pruning router node %s", inet_ntoa(rn->p.u.prefix4)); - list_delete(paths); + list_delete_and_null(&paths); rn->info = NULL; route_unlock_node(rn); } diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 5e57426089..65437dba9e 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -210,12 +210,10 @@ static void ospf_vertex_free(void *data) // assert (listcount (v->parents) == 0); if (v->children) - list_delete(v->children); - v->children = NULL; + list_delete_and_null(&v->children); if (v->parents) - list_delete(v->parents); - v->parents = NULL; + list_delete_and_null(&v->parents); v->lsa = NULL; @@ -1089,7 +1087,7 @@ void ospf_rtrs_free(struct route_table *rtrs) for (ALL_LIST_ELEMENTS(or_list, node, nnode, or)) ospf_route_free(or); - list_delete(or_list); + list_delete_and_null(&or_list); /* Unlock the node. */ rn->info = NULL; diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 294ffe48b3..b13e833afd 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -166,8 +166,7 @@ static int ospf_mpls_te_unregister() void ospf_mpls_te_term(void) { - list_delete(OspfMplsTE.iflist); - OspfMplsTE.iflist = NULL; + list_delete_and_null(&OspfMplsTE.iflist); ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA, OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); @@ -1168,8 +1167,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf, tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance); lsa_id.s_addr = htonl(tmp); - if (!ospf) + if (!ospf) { + stream_free(s); return NULL; + } lsa_header_set(s, options, lsa_type, lsa_id, ospf->router_id); } else { @@ -2534,9 +2535,10 @@ DEFUN (show_ip_ospf_mpls_te_link, "Interface information\n" "Interface name\n") { + struct vrf *vrf; int idx_interface = 5; struct interface *ifp; - struct listnode *node, *nnode, *n1; + struct listnode *node; char *vrf_name = NULL; bool all_vrf; int inst = 0; @@ -2551,11 +2553,11 @@ DEFUN (show_ip_ospf_mpls_te_link, /* vrf input is provided could be all or specific vrf*/ if (vrf_name) { if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; - for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), - node, nnode, ifp)) + vrf = vrf_lookup_by_id(ospf->vrf_id); + FOR_ALL_INTERFACES (vrf, ifp) show_mpls_te_link_sub(vty, ifp); } return CMD_SUCCESS; @@ -2563,18 +2565,18 @@ DEFUN (show_ip_ospf_mpls_te_link, ospf = ospf_lookup_by_inst_name (inst, vrf_name); if (ospf == NULL || !ospf->oi_running) return CMD_SUCCESS; - for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, - nnode, ifp)) + vrf = vrf_lookup_by_id(ospf->vrf_id); + FOR_ALL_INTERFACES (vrf, ifp) show_mpls_te_link_sub(vty, ifp); return CMD_SUCCESS; } /* Show All Interfaces. */ if (argc == 5) { - for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; - for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, - nnode, ifp)) + vrf = vrf_lookup_by_id(ospf->vrf_id); + FOR_ALL_INTERFACES (vrf, ifp) show_mpls_te_link_sub(vty, ifp); } } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 3840bc4170..f53efa4355 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -171,6 +171,18 @@ static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty, return ospf; } +static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty, + json_object *json) +{ + if (ospf->name) { + if (json) + json_object_string_add(json, "vrfName", ospf->name); + else + vty_out(vty, "VRF Name: %s\n", ospf->name); + } + +} + #ifndef VTYSH_EXTRACT_PL #include "ospf_vty_clippy.c" #endif @@ -333,13 +345,14 @@ DEFPY (no_ospf_router_id, static void ospf_passive_interface_default(struct ospf *ospf, u_char newval) { + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); struct listnode *ln; struct interface *ifp; struct ospf_interface *oi; ospf->passive_interface_default = newval; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), ln, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), passive_interface)) UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface); @@ -413,7 +426,7 @@ DEFUN (ospf_passive_interface, return CMD_SUCCESS; } - ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id); + ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, 0); if (ifp == NULL) { vty_out(vty, "interface %s not found.\n", (char *)argv[1]->arg); @@ -485,7 +498,7 @@ DEFUN (no_ospf_passive_interface, return CMD_SUCCESS; } - ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id); + ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id, 0); if (ifp == NULL) { vty_out(vty, "interface %s not found.\n", (char *)argv[1]->arg); @@ -2457,9 +2470,9 @@ DEFUN (ospf_auto_cost_reference_bandwidth, "The reference bandwidth in terms of Mbits per second\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); int idx_number = 2; u_int32_t refbw; - struct listnode *node; struct interface *ifp; refbw = strtol(argv[idx_number]->arg, NULL, 10); @@ -2473,7 +2486,7 @@ DEFUN (ospf_auto_cost_reference_bandwidth, return CMD_SUCCESS; ospf->ref_bandwidth = refbw; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ospf_if_recalculate_output_cost(ifp); return CMD_SUCCESS; @@ -2488,7 +2501,7 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth, "The reference bandwidth in terms of Mbits per second\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - struct listnode *node, *nnode; + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); struct interface *ifp; if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH) @@ -2499,7 +2512,7 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth, vty_out(vty, " Please ensure reference bandwidth is consistent across all routers\n"); - for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ospf_if_recalculate_output_cost(ifp); return CMD_SUCCESS; @@ -2890,6 +2903,8 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf, } } + ospf_show_vrf_name(ospf, vty, json); + /* Show Router ID. */ if (use_json) { json_object_string_add(json, "routerId", @@ -3555,7 +3570,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, int iface_argv, u_char use_json) { struct interface *ifp; - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); json_object *json = NULL; json_object *json_interface_sub = NULL; @@ -3573,8 +3588,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, if (argc == iface_argv) { /* Show All Interfaces.*/ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), - node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if (ospf_oi_count(ifp)) { if (use_json) json_interface_sub = @@ -3857,6 +3871,8 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } + ospf_show_vrf_name(ospf, vty, json); + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) show_ip_ospf_neighbor_sub(vty, oi, json, use_json); @@ -4146,6 +4162,8 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } + ospf_show_vrf_name(ospf, vty, json); + /*ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);*/ ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg); if (!ifp) { @@ -4558,6 +4576,8 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } + ospf_show_vrf_name(ospf, vty, json); + ret = inet_aton(argv[arg_base]->arg, &router_id); if (!ret) { if (!use_json) @@ -4657,6 +4677,8 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } + ospf_show_vrf_name(ospf, vty, json); + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { struct route_node *rn; struct ospf_neighbor *nbr; @@ -4781,6 +4803,8 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } + ospf_show_vrf_name(ospf, vty, json); + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { struct route_node *rn; struct ospf_neighbor *nbr; @@ -5591,6 +5615,8 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, if (ospf->instance) vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + ospf_show_vrf_name(ospf, vty, NULL); + vty_out(vty, "\n OSPF Router with ID (%s)\n\n", inet_ntoa(ospf->router_id)); @@ -5812,6 +5838,8 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, if (ospf->instance) vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + ospf_show_vrf_name(ospf, vty, NULL); + vty_out(vty, "\n OSPF Router with ID (%s)\n\n", inet_ntoa(ospf->router_id)); @@ -8368,6 +8396,8 @@ static int show_ip_ospf_border_routers_common(struct vty *vty, if (ospf->instance) vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + ospf_show_vrf_name(ospf, vty, NULL); + if (ospf->new_table == NULL) { vty_out(vty, "No OSPF routing information exist\n"); return CMD_SUCCESS; @@ -8460,6 +8490,8 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf) if (ospf->instance) vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + ospf_show_vrf_name(ospf, vty, NULL); + if (ospf->new_table == NULL) { vty_out(vty, "No OSPF routing information exist\n"); return CMD_SUCCESS; @@ -8633,22 +8665,20 @@ const char *ospf_int_type_str[] = {"unknown", /* should never be used. */ static int config_write_interface_one(struct vty *vty, struct ospf *ospf) { - struct listnode *n1, *n2; + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); + struct listnode *node; struct interface *ifp; struct crypt_key *ck; struct route_node *rn = NULL; struct ospf_if_params *params; int write = 0; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct vrf *vrf = NULL; if (memcmp(ifp->name, "VLINK", 5) == 0) continue; - if (ifp->ifindex == IFINDEX_DELETED) - continue; - vrf = vrf_lookup_by_id(ifp->vrf_id); vty_frame(vty, "!\n"); @@ -8729,7 +8759,7 @@ static int config_write_interface_one(struct vty *vty, struct ospf *ospf) /* Cryptographic Authentication Key print. */ if (params && params->auth_crypt) { for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, - n2, ck)) { + node, ck)) { vty_out(vty, " ip ospf message-digest-key %d md5 %s", ck->key_id, ck->auth_key); @@ -9234,6 +9264,7 @@ static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf) static int ospf_config_write_one(struct vty *vty, struct ospf *ospf) { + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); struct interface *ifp; struct ospf_interface *oi; struct listnode *node = NULL; @@ -9328,7 +9359,7 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf) if (ospf->passive_interface_default == OSPF_IF_PASSIVE) vty_out(vty, " passive-interface default\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), passive_interface) && IF_DEF_PARAMS(ifp)->passive_interface @@ -9591,14 +9622,14 @@ DEFUN (clear_ip_ospf_interface, { int idx_ifname = 4; struct interface *ifp; - struct listnode *node, *n1; + struct listnode *node; struct ospf *ospf = NULL; if (argc == 4) /* Clear all the ospfv2 interfaces. */ { - for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), - node, ifp)) + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); + FOR_ALL_INTERFACES (vrf, ifp) ospf_interface_clear(ifp); } } else { diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index d8fd9afbd7..7e6146e0d3 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -166,7 +166,7 @@ static int ospf_interface_delete(int command, struct zclient *zclient, if (rn->info) ospf_if_free((struct ospf_interface *)rn->info); - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } @@ -179,8 +179,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s, stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); /* And look it up. */ - return if_lookup_by_name_len( - ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id); + return if_lookup_by_name(ifname_tmp, vrf_id); } static int ospf_interface_state_up(int command, struct zclient *zclient, @@ -574,8 +573,7 @@ void ospf_external_del(u_char type, u_short instance) listnode_delete(om->external[type], ext); if (!om->external[type]->count) { - list_free(om->external[type]); - om->external[type] = NULL; + list_delete_and_null(&om->external[type]); } XFREE(MTYPE_OSPF_EXTERNAL, ext); } @@ -633,8 +631,7 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance) if (red) { listnode_delete(ospf->redist[type], red); if (!ospf->redist[type]->count) { - list_free(ospf->redist[type]); - ospf->redist[type] = NULL; + list_delete_and_null(&ospf->redist[type]); } ospf_routemap_unset(red); XFREE(MTYPE_OSPF_REDISTRIBUTE, red); @@ -1136,12 +1133,16 @@ void ospf_distribute_list_update(struct ospf *ospf, int type, /* External info does not exist. */ ext = ospf_external_lookup(type, instance); - if (!ext || !(rt = EXTERNAL_INFO(ext))) + if (!ext || !(rt = EXTERNAL_INFO(ext))) { + XFREE(MTYPE_OSPF_DIST_ARGS, args); return; + } /* If exists previously invoked thread, then let it continue. */ - if (ospf->t_distribute_update) + if (ospf->t_distribute_update) { + XFREE(MTYPE_OSPF_DIST_ARGS, args); return; + } /* Set timer. */ ospf->t_distribute_update = NULL; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 507c97d979..9e1cf81160 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -86,6 +86,7 @@ static void ospf_finish_final(struct ospf *); void ospf_router_id_update(struct ospf *ospf) { + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); struct in_addr router_id, router_id_old; struct ospf_interface *oi; struct interface *ifp; @@ -209,7 +210,7 @@ void ospf_router_id_update(struct ospf *ospf) ospf_router_lsa_update(ospf); /* update ospf_interface's */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ospf_if_update(ospf, ifp); } } @@ -581,6 +582,7 @@ void ospf_finish(struct ospf *ospf) /* Final cleanup of ospf instance */ static void ospf_finish_final(struct ospf *ospf) { + struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); struct route_node *rn; struct ospf_nbr_nbma *nbr_nbma; struct ospf_lsa *lsa; @@ -591,7 +593,6 @@ static void ospf_finish_final(struct ospf *ospf) struct listnode *node, *nnode; int i; u_short instance = 0; - struct vrf *vrf = NULL; QOBJ_UNREG(ospf); @@ -620,10 +621,10 @@ static void ospf_finish_final(struct ospf *ospf) for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data)) ospf_vl_delete(ospf, vl_data); - list_delete(ospf->vlinks); + list_delete_and_null(&ospf->vlinks); /* Remove any ospf interface config params */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct ospf_if_params *params; params = IF_DEF_PARAMS(ifp); @@ -634,6 +635,7 @@ static void ospf_finish_final(struct ospf *ospf) /* Reset interface. */ for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) ospf_if_free(oi); + list_delete_and_null(&ospf->oiflist); /* De-Register VRF */ ospf_zebra_vrf_deregister(ospf); @@ -734,9 +736,8 @@ static void ospf_finish_final(struct ospf *ospf) ospf_ase_external_lsas_finish(ospf->external_lsas); } - list_delete(ospf->areas); - list_delete(ospf->oi_write_q); - list_delete(ospf->oiflist); + list_delete_and_null(&ospf->areas); + list_delete_and_null(&ospf->oi_write_q); for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) { struct list *ext_list; @@ -828,6 +829,8 @@ static void ospf_area_free(struct ospf_area *area) struct route_node *rn; struct ospf_lsa *lsa; + ospf_opaque_type10_lsa_term(area); + /* Free LSDBs. */ LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) ospf_discard_from_db(area->ospf, area->lsdb, lsa); @@ -852,7 +855,7 @@ static void ospf_area_free(struct ospf_area *area) ospf_lsa_unlock(&area->router_lsa_self); route_table_finish(area->ranges); - list_delete(area->oiflist); + list_delete_and_null(&area->oiflist); if (EXPORT_NAME(area)) free(EXPORT_NAME(area)); @@ -1252,15 +1255,15 @@ static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp, static void ospf_network_run(struct prefix *p, struct ospf_area *area) { + struct vrf *vrf = vrf_lookup_by_id(area->ospf->vrf_id); struct interface *ifp; - struct listnode *node; /* Schedule Router ID Update. */ if (area->ospf->router_id.s_addr == 0) ospf_router_id_update(area->ospf); /* Get target interface. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(area->ospf->vrf_id), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ospf_network_run_interface(area->ospf, ifp, p, area); } @@ -1276,7 +1279,7 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi) if ((lst = (struct list *)rn->info)) { for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */ - list_delete(lst); + list_delete_and_null(&lst); rn->info = NULL; } diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index 314162c78b..f8903d71e9 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -292,7 +292,6 @@ static int pim_bfd_nbr_replay(int command, struct zclient *zclient, struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; struct pim_neighbor *neigh = NULL; - struct listnode *node; struct listnode *neigh_node; struct listnode *neigh_nextnode; struct vrf *vrf = NULL; @@ -301,7 +300,7 @@ static int pim_bfd_nbr_replay(int command, struct zclient *zclient, bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 144785a5cd..a9239c2835 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -214,7 +214,6 @@ static void pim_show_assert(struct pim_instance *pim, struct vty *vty) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; - struct listnode *if_node; struct interface *ifp; time_t now; @@ -223,7 +222,7 @@ static void pim_show_assert(struct pim_instance *pim, struct vty *vty) vty_out(vty, "Interface Address Source Group State Winner Uptime Timer\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -263,7 +262,6 @@ static void pim_show_assert_internal_helper(struct vty *vty, static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty) { struct pim_interface *pim_ifp; - struct listnode *if_node; struct pim_ifchannel *ch; struct interface *ifp; @@ -275,7 +273,7 @@ static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty) vty_out(vty, "Interface Address Source Group CA eCA ATD eATD\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -317,14 +315,13 @@ static void pim_show_assert_metric_helper(struct vty *vty, static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty) { struct pim_interface *pim_ifp; - struct listnode *if_node; struct pim_ifchannel *ch; struct interface *ifp; vty_out(vty, "Interface Address Source Group RPT Pref Metric Address \n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -379,7 +376,6 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty, static void pim_show_assert_winner_metric(struct pim_instance *pim, struct vty *vty) { - struct listnode *if_node; struct pim_interface *pim_ifp; struct pim_ifchannel *ch; struct interface *ifp; @@ -387,7 +383,7 @@ static void pim_show_assert_winner_metric(struct pim_instance *pim, vty_out(vty, "Interface Address Source Group RPT Pref Metric Address \n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -467,7 +463,6 @@ static void pim_show_membership_helper(struct vty *vty, static void pim_show_membership(struct pim_instance *pim, struct vty *vty, u_char uj) { - struct listnode *if_node; struct pim_interface *pim_ifp; struct pim_ifchannel *ch; struct interface *ifp; @@ -477,7 +472,7 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty, json = json_object_new_object(); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -585,7 +580,6 @@ static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, u_char uj) { - struct listnode *node; struct interface *ifp; time_t now; json_object *json = NULL; @@ -599,7 +593,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, vty_out(vty, "Interface State Address V Querier Query Timer Uptime\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp; struct listnode *sock_node; struct igmp_sock *igmp; @@ -666,7 +660,6 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, { struct igmp_sock *igmp; struct interface *ifp; - struct listnode *node; struct listnode *sock_node; struct pim_interface *pim_ifp; char uptime[10]; @@ -690,7 +683,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, now = pim_time_monotonic_sec(); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -866,7 +859,6 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty) { - struct listnode *node; struct interface *ifp; time_t now; @@ -875,7 +867,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty) vty_out(vty, "Interface Address Source Group Socket Uptime \n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp; struct listnode *join_node; struct igmp_join *ij; @@ -922,7 +914,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim, struct in_addr ifaddr; struct interface *ifp; struct listnode *neighnode; - struct listnode *node; struct listnode *upnode; struct pim_interface *pim_ifp; struct pim_neighbor *neigh; @@ -956,7 +947,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim, if (uj) json = json_object_new_object(); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -1063,58 +1054,48 @@ static void pim_show_interfaces_single(struct pim_instance *pim, // FHR for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) { - if (ifp == up->rpf.source_nexthop.interface) { - if (up->flags - & PIM_UPSTREAM_FLAG_MASK_FHR) { - if (!json_fhr_sources) { - json_fhr_sources = - json_object_new_object(); - } - - pim_inet4_dump("<src?>", - up->sg.src, - src_str, - sizeof(src_str)); - pim_inet4_dump("<grp?>", - up->sg.grp, - grp_str, - sizeof(grp_str)); - pim_time_uptime( - uptime, sizeof(uptime), - now - up->state_transition); - - /* Does this group live in - * json_fhr_sources? If not - * create it. */ - json_object_object_get_ex( - json_fhr_sources, - grp_str, &json_group); - - if (!json_group) { - json_group = - json_object_new_object(); - json_object_object_add( - json_fhr_sources, - grp_str, - json_group); - } - - json_group_source = - json_object_new_object(); - json_object_string_add( - json_group_source, - "source", src_str); - json_object_string_add( - json_group_source, - "group", grp_str); - json_object_string_add( - json_group_source, - "upTime", uptime); - json_object_object_add( - json_group, src_str, - json_group_source); - } + if (ifp != up->rpf.source_nexthop.interface) + continue; + + if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)) + continue; + + if (!json_fhr_sources) + json_fhr_sources = + json_object_new_object(); + + pim_inet4_dump("<src?>", up->sg.src, + src_str, sizeof(src_str)); + pim_inet4_dump("<grp?>", up->sg.grp, + grp_str, sizeof(grp_str)); + pim_time_uptime(uptime, sizeof(uptime), + now - up->state_transition); + + /* + * Does this group live in json_fhr_sources? + * If not create it. + */ + json_object_object_get_ex(json_fhr_sources, + grp_str, + &json_group); + + if (!json_group) { + json_group = json_object_new_object(); + json_object_object_add( + json_fhr_sources, + grp_str, + json_group); } + + json_group_source = json_object_new_object(); + json_object_string_add(json_group_source, + "source", src_str); + json_object_string_add(json_group_source, + "group", grp_str); + json_object_string_add(json_group_source, + "upTime", uptime); + json_object_object_add(json_group, src_str, + json_group_source); } if (json_fhr_sources) { @@ -1237,37 +1218,33 @@ static void pim_show_interfaces_single(struct pim_instance *pim, print_header = 1; for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) { - if (strcmp(ifp->name, up->rpf.source_nexthop - .interface->name) - == 0) { - if (up->flags - & PIM_UPSTREAM_FLAG_MASK_FHR) { - - if (print_header) { - vty_out(vty, - "FHR - First Hop Router\n"); - vty_out(vty, - "----------------------\n"); - print_header = 0; - } - - pim_inet4_dump("<src?>", - up->sg.src, - src_str, - sizeof(src_str)); - pim_inet4_dump("<grp?>", - up->sg.grp, - grp_str, - sizeof(grp_str)); - pim_time_uptime( - uptime, sizeof(uptime), - now - up->state_transition); - vty_out(vty, - "%s : %s is a source, uptime is %s\n", - grp_str, src_str, - uptime); - } + + if (strcmp(ifp->name, + up->rpf.source_nexthop. + interface->name) != 0) + continue; + + if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)) + continue; + + if (print_header) { + vty_out(vty, + "FHR - First Hop Router\n"); + vty_out(vty, + "----------------------\n"); + print_header = 0; } + + pim_inet4_dump("<src?>", up->sg.src, + src_str, sizeof(src_str)); + pim_inet4_dump("<grp?>", up->sg.grp, + grp_str, sizeof(grp_str)); + pim_time_uptime(uptime, sizeof(uptime), + now - up->state_transition); + vty_out(vty, + "%s : %s is a source, uptime is %s\n", + grp_str, src_str, + uptime); } if (!print_header) { @@ -1338,7 +1315,6 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, u_char uj) { struct interface *ifp; - struct listnode *node; struct listnode *upnode; struct pim_interface *pim_ifp; struct pim_upstream *up; @@ -1351,7 +1327,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, json = json_object_new_object(); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -1433,7 +1409,6 @@ static void pim_show_interface_traffic(struct pim_instance *pim, { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; - struct listnode *node = NULL; json_object *json = NULL; json_object *json_row = NULL; @@ -1451,7 +1426,7 @@ static void pim_show_interface_traffic(struct pim_instance *pim, "---------------------------------------------------------------------------------------------------------------\n"); } - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -1514,7 +1489,6 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim, { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; - struct listnode *node = NULL; json_object *json = NULL; json_object *json_row = NULL; uint8_t found_ifname = 0; @@ -1533,7 +1507,7 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim, "---------------------------------------------------------------------------------------------------------------\n"); } - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { if (strcmp(ifname, ifp->name)) continue; @@ -1678,7 +1652,6 @@ static void pim_show_join_helper(struct vty *vty, static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj) { - struct listnode *if_node; struct pim_interface *pim_ifp; struct pim_ifchannel *ch; struct interface *ifp; @@ -1693,7 +1666,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj) vty_out(vty, "Interface Address Source Group State Uptime Expire Prune\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -1713,7 +1686,6 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj) static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty, const char *neighbor, u_char uj) { - struct listnode *node; struct listnode *neighnode; struct interface *ifp; struct pim_interface *pim_ifp; @@ -1739,7 +1711,7 @@ static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty, if (uj) json = json_object_new_object(); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -2125,7 +2097,6 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty, static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty, u_char uj) { - struct listnode *node; struct listnode *neighnode; struct interface *ifp; struct pim_interface *pim_ifp; @@ -2147,7 +2118,7 @@ static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty, "Interface Neighbor Uptime Holdtime DR Pri\n"); } - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -2208,13 +2179,12 @@ static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty, static void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty) { - struct listnode *node; struct interface *ifp; vty_out(vty, "Interface Address Neighbor Secondary \n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp; struct in_addr ifaddr; struct listnode *neighnode; @@ -2400,6 +2370,30 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty, json_object_string_add( json_row, "inboundInterface", up->rpf.source_nexthop.interface->name); + + /* + * The RPF address we use is slightly different + * based upon what we are looking up. + * If we have a S, list that unless + * we are the FHR, else we just put + * the RP as the rpfAddress + */ + if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR || + up->sg.src.s_addr == INADDR_ANY) { + char rpf[PREFIX_STRLEN]; + struct pim_rpf *rpg; + + rpg = RP(pim, up->sg.grp); + pim_inet4_dump("<rpf?>", + rpg->rpf_addr.u.prefix4, + rpf, sizeof(rpf)); + json_object_string_add(json_row, + "rpfAddress", rpf); + } else { + json_object_string_add(json_row, + "rpfAddress", src_str); + } + json_object_string_add(json_row, "source", src_str); json_object_string_add(json_row, "group", grp_str); json_object_string_add(json_row, "state", state_str); @@ -2507,7 +2501,6 @@ static void pim_show_join_desired_helper(struct pim_instance *pim, static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, u_char uj) { - struct listnode *if_node; struct pim_interface *pim_ifp; struct pim_ifchannel *ch; struct interface *ifp; @@ -2521,7 +2514,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n"); /* scan per-interface (S,G) state */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) continue; @@ -2802,7 +2795,6 @@ static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty) static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, u_char uj) { - struct listnode *ifnode; struct interface *ifp; time_t now; json_object *json = NULL; @@ -2818,7 +2810,7 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, "Interface Address Group Mode Timer Srcs V Uptime \n"); /* scan interfaces */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; struct listnode *sock_node; struct igmp_sock *igmp; @@ -2924,14 +2916,13 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, static void igmp_show_group_retransmission(struct pim_instance *pim, struct vty *vty) { - struct listnode *ifnode; struct interface *ifp; vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs\n"); /* scan interfaces */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; struct listnode *sock_node; struct igmp_sock *igmp; @@ -2989,7 +2980,6 @@ static void igmp_show_group_retransmission(struct pim_instance *pim, static void igmp_show_sources(struct pim_instance *pim, struct vty *vty) { - struct listnode *ifnode; struct interface *ifp; time_t now; @@ -2999,7 +2989,7 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty) "Interface Address Group Source Timer Fwd Uptime \n"); /* scan interfaces */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; struct listnode *sock_node; struct igmp_sock *igmp; @@ -3066,14 +3056,13 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty) static void igmp_show_source_retransmission(struct pim_instance *pim, struct vty *vty) { - struct listnode *ifnode; struct interface *ifp; vty_out(vty, "Interface Address Group Source Counter\n"); /* scan interfaces */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; struct listnode *sock_node; struct igmp_sock *igmp; @@ -3125,29 +3114,20 @@ static void igmp_show_source_retransmission(struct pim_instance *pim, static void clear_igmp_interfaces(struct pim_instance *pim) { - struct listnode *ifnode; - struct listnode *ifnextnode; struct interface *ifp; - for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode, - ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) pim_if_addr_del_all_igmp(ifp); - } - for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode, - ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) pim_if_addr_add_all(ifp); - } } static void clear_pim_interfaces(struct pim_instance *pim) { - struct listnode *ifnode; - struct listnode *ifnextnode; struct interface *ifp; - for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode, - ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { if (ifp->info) { pim_neighbor_delete_all(ifp, "interface cleared"); } @@ -3160,12 +3140,12 @@ static void clear_interfaces(struct pim_instance *pim) clear_pim_interfaces(pim); } -#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \ - pim_ifp = ifp->info; \ - if (!pim_ifp) { \ - vty_out(vty, \ +#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \ + pim_ifp = ifp->info; \ + if (!pim_ifp) { \ + vty_out(vty, \ "%% Enable PIM and/or IGMP on this interface first\n"); \ - return CMD_WARNING_CONFIG_FAILED; \ + return CMD_WARNING_CONFIG_FAILED; \ } DEFUN (clear_ip_interfaces, @@ -3301,16 +3281,13 @@ DEFUN (clear_ip_pim_interface_traffic, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - struct listnode *ifnode = NULL; - struct listnode *ifnextnode = NULL; struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; if (!vrf) return CMD_WARNING; - for (ALL_LIST_ELEMENTS(vrf_iflist(vrf->vrf_id), ifnode, ifnextnode, - ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { pim_ifp = ifp->info; if (!pim_ifp) @@ -4320,7 +4297,6 @@ DEFUN (show_ip_pim_interface_traffic, static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty) { - struct listnode *node; struct interface *ifp; vty_out(vty, "\n"); @@ -4328,7 +4304,7 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty) vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp; struct in_addr ifaddr; struct sioc_vif_req vreq; @@ -6480,7 +6456,7 @@ DEFUN(interface_ip_pim_boundary_oil, "Generic multicast configuration options\n" "Define multicast boundary\n" "Filter OIL by group using prefix list\n" - "Prefix list to filter OIL with") + "Prefix list to filter OIL with\n") { VTY_DECLVAR_CONTEXT(interface, iif); struct pim_interface *pim_ifp; @@ -6508,11 +6484,11 @@ DEFUN(interface_no_ip_pim_boundary_oil, "Generic multicast configuration options\n" "Define multicast boundary\n" "Filter OIL by group using prefix list\n" - "Prefix list to filter OIL with") + "Prefix list to filter OIL with\n") { VTY_DECLVAR_CONTEXT(interface, iif); struct pim_interface *pim_ifp; - int idx; + int idx = 0; argv_find(argv, argc, "WORD", &idx); diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c index 138a110d3a..08a1432bb0 100644 --- a/pimd/pim_hello.c +++ b/pimd/pim_hello.c @@ -125,9 +125,9 @@ static void tlv_trace_list(const char *label, const char *tlv_name, } } -#define FREE_ADDR_LIST \ - if (hello_option_addr_list) { \ - list_delete(hello_option_addr_list); \ +#define FREE_ADDR_LIST \ + if (hello_option_addr_list) { \ + list_delete_and_null(&hello_option_addr_list); \ } #define FREE_ADDR_LIST_THEN_RETURN(code) \ diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index b8cbed7f93..5dc64a1b3f 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -71,19 +71,19 @@ static void *if_list_clean(struct pim_interface *pim_ifp) struct pim_ifchannel *ch; if (pim_ifp->igmp_join_list) - list_delete(pim_ifp->igmp_join_list); + list_delete_and_null(&pim_ifp->igmp_join_list); if (pim_ifp->igmp_socket_list) - list_delete(pim_ifp->igmp_socket_list); + list_delete_and_null(&pim_ifp->igmp_socket_list); if (pim_ifp->pim_neighbor_list) - list_delete(pim_ifp->pim_neighbor_list); + list_delete_and_null(&pim_ifp->pim_neighbor_list); if (pim_ifp->upstream_switch_list) - list_delete(pim_ifp->upstream_switch_list); + list_delete_and_null(&pim_ifp->upstream_switch_list); if (pim_ifp->sec_addr_list) - list_delete(pim_ifp->sec_addr_list); + list_delete_and_null(&pim_ifp->sec_addr_list); while ((ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) != NULL) @@ -241,10 +241,10 @@ void pim_if_delete(struct interface *ifp) pim_if_del_vif(ifp); - list_delete(pim_ifp->igmp_socket_list); - list_delete(pim_ifp->pim_neighbor_list); - list_delete(pim_ifp->upstream_switch_list); - list_delete(pim_ifp->sec_addr_list); + list_delete_and_null(&pim_ifp->igmp_socket_list); + list_delete_and_null(&pim_ifp->pim_neighbor_list); + list_delete_and_null(&pim_ifp->upstream_switch_list); + list_delete_and_null(&pim_ifp->sec_addr_list); if (pim_ifp->boundary_oil_plist) XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist); @@ -1023,10 +1023,9 @@ int pim_if_del_vif(struct interface *ifp) struct interface *pim_if_find_by_vif_index(struct pim_instance *pim, ifindex_t vif_index) { - struct listnode *ifnode; struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { if (ifp->info) { struct pim_interface *pim_ifp; pim_ifp = ifp->info; @@ -1373,7 +1372,7 @@ int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr, listnode_delete(pim_ifp->igmp_join_list, ij); igmp_join_free(ij); if (listcount(pim_ifp->igmp_join_list) < 1) { - list_delete(pim_ifp->igmp_join_list); + list_delete_and_null(&pim_ifp->igmp_join_list); pim_ifp->igmp_join_list = 0; } @@ -1480,17 +1479,16 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp) */ void pim_if_create_pimreg(struct pim_instance *pim) { - char pimreg_name[100]; + char pimreg_name[INTERFACE_NAMSIZ]; if (!pim->regiface) { if (pim->vrf_id == VRF_DEFAULT) - strcpy(pimreg_name, "pimreg"); + strlcpy(pimreg_name, "pimreg", sizeof(pimreg_name)); else - sprintf(pimreg_name, "pimreg%d", - pim->vrf->data.l.table_id); + snprintf(pimreg_name, sizeof(pimreg_name), "pimreg%u", + pim->vrf->data.l.table_id); - pim->regiface = if_create(pimreg_name, strlen(pimreg_name), - pim->vrf_id); + pim->regiface = if_create(pimreg_name, pim->vrf_id); pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF; pim_if_new(pim->regiface, 0, 0); diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index bcf7d2318d..5f597b17b1 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -169,7 +169,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) pim_ifchannel_remove_children(ch); if (ch->sources) - list_delete(ch->sources); + list_delete_and_null(&ch->sources); listnode_delete(ch->upstream->ifchannels, ch); @@ -571,7 +571,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_ifchannel_remove_children(ch); if (ch->sources) - list_delete(ch->sources); + list_delete_and_null(&ch->sources); THREAD_OFF(ch->t_ifjoin_expiry_timer); THREAD_OFF(ch->t_ifjoin_prune_pending_timer); @@ -1291,10 +1291,9 @@ void pim_ifchannel_scan_forward_start(struct interface *new_ifp) { struct pim_interface *new_pim_ifp = new_ifp->info; struct pim_instance *pim = new_pim_ifp->pim; - struct listnode *ifnode; struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *loop_pim_ifp = ifp->info; struct pim_ifchannel *ch; diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index f6c8db7acb..7524119e52 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -696,7 +696,7 @@ void igmp_startup_mode_on(struct igmp_sock *igmp) static void igmp_group_free(struct igmp_group *group) { - list_delete(group->group_source_list); + list_delete_and_null(&group->group_source_list); XFREE(MTYPE_PIM_IGMP_GROUP, group); } @@ -748,7 +748,7 @@ void igmp_sock_free(struct igmp_sock *igmp) zassert(igmp->igmp_group_list); zassert(!listcount(igmp->igmp_group_list)); - list_delete(igmp->igmp_group_list); + list_delete_and_null(&igmp->igmp_group_list); hash_free(igmp->igmp_group_hash); XFREE(MTYPE_PIM_IGMP_SOCKET, igmp); diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index 42feae3361..1fccbaeafa 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -48,7 +48,7 @@ static void pim_instance_terminate(struct pim_instance *pim) } if (pim->static_routes) - list_delete(pim->static_routes); + list_delete_and_null(&pim->static_routes); pim_rp_free(pim); diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index 8e0b4ab5e8..e87dfbca95 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -32,7 +32,7 @@ void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag) { - list_delete(jag->sources); + list_delete_and_null(&jag->sources); XFREE(MTYPE_PIM_JP_AGG_GROUP, jag); } @@ -108,8 +108,7 @@ void pim_jp_agg_clear_group(struct list *group) js->up = NULL; XFREE(MTYPE_PIM_JP_AGG_SOURCE, js); } - list_delete(jag->sources); - jag->sources = NULL; + list_delete_and_null(&jag->sources); listnode_delete(group, jag); XFREE(MTYPE_PIM_JP_AGG_GROUP, jag); } @@ -169,8 +168,7 @@ void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up) } if (jag->sources->count == 0) { - list_delete(jag->sources); - jag->sources = NULL; + list_delete_and_null(&jag->sources); listnode_delete(group, jag); XFREE(MTYPE_PIM_JP_AGG_GROUP, jag); } @@ -214,12 +212,11 @@ int pim_jp_agg_is_in_list(struct list *group, struct pim_upstream *up) void pim_jp_agg_upstream_verification(struct pim_upstream *up, bool ignore) { #ifdef PIM_JP_AGG_DEBUG - struct listnode *node; struct interface *ifp; struct pim_interface *pim_ifp = up->rpf.source_nexthop.interface->info; struct pim_instance *pim = pim_ifp->pim; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { pim_ifp = ifp->info; struct listnode *nnode; diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 4b049d90ad..53a3382987 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1261,7 +1261,7 @@ static void pim_msdp_mg_free(struct pim_instance *pim, struct pim_msdp_mg *mg) XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name); if (mg->mbr_list) - list_delete(mg->mbr_list); + list_delete_and_null(&mg->mbr_list); XFREE(MTYPE_PIM_MSDP_MG, mg); pim->msdp.mg = NULL; @@ -1619,8 +1619,7 @@ void pim_msdp_exit(struct pim_instance *pim) } if (pim->msdp.peer_list) { - list_delete(pim->msdp.peer_list); - pim->msdp.peer_list = NULL; + list_delete_and_null(&pim->msdp.peer_list); } if (pim->msdp.sa_hash) { @@ -1629,7 +1628,6 @@ void pim_msdp_exit(struct pim_instance *pim) } if (pim->msdp.sa_list) { - list_delete(pim->msdp.sa_list); - pim->msdp.sa_list = NULL; + list_delete_and_null(&pim->msdp.sa_list); } } diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 04e3e10ff3..dd77e2b084 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -401,8 +401,7 @@ static void delete_prefix_list(struct pim_neighbor *neigh) } #endif - list_delete(neigh->prefix_list); - neigh->prefix_list = 0; + list_delete_and_null(&neigh->prefix_list); } } @@ -412,7 +411,7 @@ void pim_neighbor_free(struct pim_neighbor *neigh) delete_prefix_list(neigh); - list_delete(neigh->upstream_jp_agg); + list_delete_and_null(&neigh->upstream_jp_agg); THREAD_OFF(neigh->jp_timer); XFREE(MTYPE_PIM_NEIGHBOR, neigh); diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 7a380796a1..8f9058d994 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -236,7 +236,7 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr, pim_sendmsg_zebra_rnh(pim, zclient, pnc, ZEBRA_NEXTHOP_UNREGISTER); - list_delete(pnc->rp_list); + list_delete_and_null(&pnc->rp_list); hash_free(pnc->upstream_hash); hash_release(pim->rpf_hash, pnc); @@ -410,12 +410,12 @@ static int pim_update_upstream_nh_helper(struct hash_backet *backet, void *arg) static int pim_update_upstream_nh(struct pim_instance *pim, struct pim_nexthop_cache *pnc) { - struct listnode *node, *ifnode; + struct listnode *node; struct interface *ifp; hash_walk(pnc->upstream_hash, pim_update_upstream_nh_helper, pim); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) + FOR_ALL_INTERFACES (pim->vrf, ifp) if (ifp->info) { struct pim_interface *pim_ifp = ifp->info; struct pim_iface_upstream_switch *us; diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 9ab0709d3e..c45b0ce14c 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -123,8 +123,7 @@ void pim_oil_init(struct pim_instance *pim) void pim_oil_terminate(struct pim_instance *pim) { if (pim->channel_oil_list) - list_delete(pim->channel_oil_list); - pim->channel_oil_list = NULL; + list_delete_and_null(&pim->channel_oil_list); if (pim->channel_oil_hash) hash_free(pim->channel_oil_hash); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 5c7561f586..d961aa4c49 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -51,8 +51,7 @@ void pim_rp_list_hash_clean(void *data) { struct pim_nexthop_cache *pnc = (struct pim_nexthop_cache *)data; - list_delete(pnc->rp_list); - pnc->rp_list = NULL; + list_delete_and_null(&pnc->rp_list); hash_clean(pnc->upstream_hash, NULL); hash_free(pnc->upstream_hash); @@ -110,7 +109,7 @@ void pim_rp_init(struct pim_instance *pim) pim->rp_table = route_table_init(); if (!pim->rp_table) { zlog_err("Unable to alloc rp_table"); - list_delete(pim->rp_list); + list_delete_and_null(&pim->rp_list); return; } @@ -119,13 +118,13 @@ void pim_rp_init(struct pim_instance *pim) if (!rp_info) { zlog_err("Unable to alloc rp_info"); route_table_finish(pim->rp_table); - list_delete(pim->rp_list); + list_delete_and_null(&pim->rp_list); return; } if (!str2prefix("224.0.0.0/4", &rp_info->group)) { zlog_err("Unable to convert 224.0.0.0/4 to prefix"); - list_delete(pim->rp_list); + list_delete_and_null(&pim->rp_list); route_table_finish(pim->rp_table); XFREE(MTYPE_PIM_RP, rp_info); return; @@ -140,7 +139,7 @@ void pim_rp_init(struct pim_instance *pim) rn = route_node_get(pim->rp_table, &rp_info->group); if (!rn) { zlog_err("Failure to get route node for pim->rp_table"); - list_delete(pim->rp_list); + list_delete_and_null(&pim->rp_list); route_table_finish(pim->rp_table); XFREE(MTYPE_PIM_RP, rp_info); return; @@ -155,8 +154,7 @@ void pim_rp_init(struct pim_instance *pim) void pim_rp_free(struct pim_instance *pim) { if (pim->rp_list) - list_delete(pim->rp_list); - pim->rp_list = NULL; + list_delete_and_null(&pim->rp_list); } /* @@ -334,11 +332,10 @@ static int pim_rp_check_interface_addrs(struct rp_info *rp_info, static void pim_rp_check_interfaces(struct pim_instance *pim, struct rp_info *rp_info) { - struct listnode *node; struct interface *ifp; rp_info->i_am_rp = 0; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index 9e90a34687..8e7da0f121 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -50,10 +50,8 @@ void pim_ssmpingd_init(struct pim_instance *pim) void pim_ssmpingd_destroy(struct pim_instance *pim) { - if (pim->ssmpingd_list) { - list_delete(pim->ssmpingd_list); - pim->ssmpingd_list = 0; - } + if (pim->ssmpingd_list) + list_delete_and_null(&pim->ssmpingd_list); } static struct ssmpingd_sock *ssmpingd_find(struct pim_instance *pim, diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c index 6d7adf2422..3c9ef28f5a 100644 --- a/pimd/pim_tlv.c +++ b/pimd/pim_tlv.c @@ -654,12 +654,12 @@ int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags, return addr - buf; } -#define FREE_ADDR_LIST(hello_option_addr_list) \ - { \ - if (hello_option_addr_list) { \ - list_delete(hello_option_addr_list); \ - hello_option_addr_list = 0; \ - } \ +#define FREE_ADDR_LIST(hello_option_addr_list) \ + { \ + if (hello_option_addr_list) { \ + list_delete_and_null(&hello_option_addr_list); \ + hello_option_addr_list = 0; \ + } \ } int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 0bf2ce5d56..fdd37f2b91 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -82,8 +82,7 @@ static void pim_upstream_remove_children(struct pim_instance *pim, if (child) child->parent = NULL; } - list_delete(up->sources); - up->sources = NULL; + list_delete_and_null(&up->sources); } /* @@ -203,13 +202,12 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim, pim_upstream_remove_children(pim, up); if (up->sources) - list_delete(up->sources); - up->sources = NULL; + list_delete_and_null(&up->sources); + pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__); upstream_channel_oil_detach(up); - list_delete(up->ifchannels); - up->ifchannels = NULL; + list_delete_and_null(&up->ifchannels); /* notice that listnode_delete() can't be moved @@ -696,9 +694,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, pim_upstream_remove_children(pim, up); if (up->sources) - list_delete(up->sources); + list_delete_and_null(&up->sources); - list_delete(up->ifchannels); + list_delete_and_null(&up->ifchannels); hash_release(pim->upstream_hash, up); XFREE(MTYPE_PIM_UPSTREAM, up); @@ -866,12 +864,11 @@ int pim_upstream_evaluate_join_desired(struct pim_instance *pim, struct pim_upstream *up) { struct interface *ifp; - struct listnode *node; struct pim_ifchannel *ch, *starch; struct pim_upstream *starup = up->parent; int ret = 0; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { if (!ifp->info) continue; @@ -1428,7 +1425,6 @@ int pim_upstream_inherited_olist_decide(struct pim_instance *pim, struct interface *ifp; struct pim_interface *pim_ifp = NULL; struct pim_ifchannel *ch, *starch; - struct listnode *node; struct pim_upstream *starup = up->parent; int output_intf = 0; @@ -1443,7 +1439,7 @@ int pim_upstream_inherited_olist_decide(struct pim_instance *pim, up->channel_oil = pim_channel_oil_add( pim, &up->sg, pim_ifp->mroute_vif_index); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { if (!ifp->info) continue; @@ -1548,8 +1544,7 @@ unsigned int pim_upstream_hash_key(void *arg) void pim_upstream_terminate(struct pim_instance *pim) { if (pim->upstream_list) - list_delete(pim->upstream_list); - pim->upstream_list = NULL; + list_delete_and_null(&pim->upstream_list); if (pim->upstream_hash) hash_free(pim->upstream_hash); diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index c1adbcc915..450faf75bb 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -240,7 +240,6 @@ int pim_global_config_write(struct vty *vty) int pim_interface_config_write(struct vty *vty) { struct pim_instance *pim; - struct listnode *node; struct interface *ifp; struct vrf *vrf; int writes = 0; @@ -250,8 +249,7 @@ int pim_interface_config_write(struct vty *vty) if (!pim) continue; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) { - + FOR_ALL_INTERFACES (pim->vrf, ifp) { /* IF name */ if (vrf->vrf_id == VRF_DEFAULT) vty_frame(vty, "interface %s\n", ifp->name); @@ -362,7 +360,7 @@ int pim_interface_config_write(struct vty *vty) /* boundary */ if (pim_ifp->boundary_oil_plist) { vty_out(vty, - " ip pim boundary oil %s\n", + " ip multicast boundary oil %s\n", pim_ifp->boundary_oil_plist); ++writes; } diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index df70e9dd5e..db11e5f171 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -330,10 +330,10 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient, pim_rp_check_on_if_add(pim_ifp); if (if_is_loopback(c->ifp)) { - struct listnode *ifnode; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), ifnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if (!if_is_loopback(ifp) && if_is_operative(ifp)) pim_if_addr_add_all(ifp); } @@ -392,7 +392,6 @@ static int pim_zebra_if_address_del(int command, struct zclient *client, static void scan_upstream_rpf_cache() { struct listnode *up_node; - struct listnode *ifnode; struct listnode *up_nextnode; struct listnode *node; struct pim_upstream *up; @@ -501,7 +500,7 @@ static void scan_upstream_rpf_cache() if (!pim) continue; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) + FOR_ALL_INTERFACES (pim->vrf, ifp) if (ifp->info) { struct pim_interface *pim_ifp = ifp->info; struct pim_iface_upstream_switch *us; @@ -861,7 +860,6 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim, void igmp_source_forward_reevaluate_all(void) { - struct listnode *ifnode; struct interface *ifp; struct vrf *vrf; struct pim_instance *pim; @@ -871,8 +869,7 @@ void igmp_source_forward_reevaluate_all(void) if (!pim) continue; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, - ifp)) { + FOR_ALL_INTERFACES (pim->vrf, ifp) { struct pim_interface *pim_ifp = ifp->info; struct listnode *sock_node; struct igmp_sock *igmp; diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c index 56ba8e7f3e..2ce289e38f 100644 --- a/ripd/rip_debug.c +++ b/ripd/rip_debug.c @@ -93,13 +93,9 @@ DEFUN (debug_rip_packet_direct, { int idx_recv_send = 3; rip_debug_packet |= RIP_DEBUG_PACKET; - if (strncmp("send", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) + if (strcmp("send", argv[idx_recv_send]->text) == 0) rip_debug_packet |= RIP_DEBUG_SEND; - if (strncmp("recv", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) + if (strcmp("recv", argv[idx_recv_send]->text) == 0) rip_debug_packet |= RIP_DEBUG_RECV; return CMD_SUCCESS; } @@ -150,16 +146,12 @@ DEFUN (no_debug_rip_packet_direct, "RIP option set for send packet\n") { int idx_recv_send = 4; - if (strncmp("send", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) { + if (strcmp("send", argv[idx_recv_send]->text) == 0) { if (IS_RIP_DEBUG_RECV) rip_debug_packet &= ~RIP_DEBUG_SEND; else rip_debug_packet = 0; - } else if (strncmp("recv", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) { + } else if (strcmp("recv", argv[idx_recv_send]->text) == 0) { if (IS_RIP_DEBUG_SEND) rip_debug_packet &= ~RIP_DEBUG_RECV; else diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 1b2cbb61c3..9282896c28 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -336,10 +336,10 @@ static int rip_if_ipv4_address_check(struct interface *ifp) /* Does this address belongs to me ? */ int if_check_address(struct in_addr addr) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct listnode *cnode; struct connected *connected; @@ -471,7 +471,7 @@ int rip_interface_delete(int command, struct zclient *zclient, /* To support pseudo interface do not free interface structure. */ /* if_delete(ifp); */ - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } @@ -490,10 +490,10 @@ static void rip_interface_clean(struct rip_interface *ri) void rip_interfaces_clean(void) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_interface_clean(ifp->info); } @@ -542,10 +542,10 @@ static void rip_interface_reset(struct rip_interface *ri) void rip_interfaces_reset(void) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_interface_reset(ifp->info); } @@ -583,10 +583,10 @@ int rip_if_down(struct interface *ifp) /* Needed for stop RIP process. */ void rip_if_down_all() { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_if_down(ifp); } @@ -977,11 +977,11 @@ void rip_enable_apply(struct interface *ifp) /* Apply network configuration to all interface. */ void rip_enable_apply_all() { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node, *nnode; /* Check each interface. */ - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_enable_apply(ifp); } @@ -1091,10 +1091,10 @@ void rip_passive_interface_apply(struct interface *ifp) static void rip_passive_interface_apply_all(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_passive_interface_apply(ifp); } @@ -1728,15 +1728,12 @@ DEFUN (no_rip_passive_interface, /* Write rip configuration of each interface. */ static int rip_interface_config_write(struct vty *vty) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct rip_interface *ri; - if (ifp->ifindex == IFINDEX_DELETED) - continue; - ri = ifp->info; /* Do not display the interface if there is no diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c index 6b539046f5..0e0230c9d2 100644 --- a/ripd/rip_offset.c +++ b/ripd/rip_offset.c @@ -363,7 +363,7 @@ void rip_offset_init() void rip_offset_clean() { - list_delete(rip_offset_list_master); + list_delete_and_null(&rip_offset_list_master); rip_offset_list_master = list_new(); rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp; diff --git a/ripd/ripd.c b/ripd/ripd.c index 921b65009a..a4b56d9fbf 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -132,8 +132,7 @@ static int rip_garbage_collect(struct thread *t) /* Unlock route_node. */ listnode_delete(rp->info, rinfo); if (list_isempty((struct list *)rp->info)) { - list_free(rp->info); - rp->info = NULL; + list_delete_and_null((struct list **)&rp->info); route_unlock_node(rp); } @@ -373,16 +372,16 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, /* Check nexthop address validity. */ static int rip_nexthop_check(struct in_addr *addr) { - struct listnode *node; - struct listnode *cnode; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; + struct listnode *cnode; struct connected *ifc; struct prefix *p; /* If nexthop address matches local configured address then it is invalid nexthop. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) { p = ifc->address; @@ -2446,7 +2445,7 @@ static void rip_update_interface(struct connected *ifc, u_char version, /* Update send to all interface and neighbor. */ static void rip_update_process(int route_type) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct listnode *ifnode, *ifnnode; struct connected *connected; struct interface *ifp; @@ -2456,7 +2455,7 @@ static void rip_update_process(int route_type) struct prefix *p; /* Send RIP update to each interface. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if (if_is_loopback(ifp)) continue; @@ -3513,7 +3512,7 @@ DEFUN (show_ip_rip_status, "Show RIP routes\n" "IP routing protocol process parameters and statistics\n") { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct rip_interface *ri; extern const struct message ri_version_msg[]; @@ -3553,7 +3552,7 @@ DEFUN (show_ip_rip_status, vty_out(vty, " Interface Send Recv Key-chain\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; if (!ri->running) @@ -3587,7 +3586,7 @@ DEFUN (show_ip_rip_status, { int found_passive = 0; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; if ((ri->enable_network || ri->enable_interface) @@ -3772,10 +3771,10 @@ void rip_distribute_update_interface(struct interface *ifp) /* ARGSUSED */ static void rip_distribute_update_all(struct prefix_list *notused) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_distribute_update_interface(ifp); } /* ARGSUSED */ @@ -3809,7 +3808,7 @@ void rip_clean(void) RIP_TIMER_OFF(rinfo->t_garbage_collect); rip_info_free(rinfo); } - list_delete(list); + list_delete_and_null(&list); rp->info = NULL; route_unlock_node(rp); } @@ -3948,10 +3947,10 @@ static void rip_routemap_update_redistribute(void) /* ARGSUSED */ static void rip_routemap_update(const char *notused) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) rip_if_rmap_update_interface(ifp); rip_routemap_update_redistribute(); diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c index 9ebc302b1b..c8cad23add 100644 --- a/ripngd/ripng_debug.c +++ b/ripngd/ripng_debug.c @@ -94,13 +94,9 @@ DEFUN (debug_ripng_packet_direct, { int idx_recv_send = 3; ripng_debug_packet |= RIPNG_DEBUG_PACKET; - if (strncmp("send", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) + if (strcmp("send", argv[idx_recv_send]->text) == 0) ripng_debug_packet |= RIPNG_DEBUG_SEND; - if (strncmp("recv", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) + if (strcmp("recv", argv[idx_recv_send]->text) == 0) ripng_debug_packet |= RIPNG_DEBUG_RECV; return CMD_SUCCESS; @@ -152,16 +148,12 @@ DEFUN (no_debug_ripng_packet_direct, "Debug option set for send packet\n") { int idx_recv_send = 4; - if (strncmp("send", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) { + if (strcmp("send", argv[idx_recv_send]->text) == 0) { if (IS_RIPNG_DEBUG_RECV) ripng_debug_packet &= ~RIPNG_DEBUG_SEND; else ripng_debug_packet = 0; - } else if (strncmp("recv", argv[idx_recv_send]->arg, - strlen(argv[idx_recv_send]->arg)) - == 0) { + } else if (strcmp("recv", argv[idx_recv_send]->text) == 0) { if (IS_RIPNG_DEBUG_SEND) ripng_debug_packet &= ~RIPNG_DEBUG_RECV; else diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index 5c65f522ef..d450d5a7f9 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -299,18 +299,18 @@ int ripng_interface_delete(int command, struct zclient *zclient, /* To support pseudo interface do not free interface structure. */ /* if_delete(ifp); */ - ifp->ifindex = IFINDEX_DELETED; + if_set_index(ifp, IFINDEX_INTERNAL); return 0; } void ripng_interface_clean(void) { - struct listnode *node, *nnode; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct ripng_interface *ri; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; ri->enable_network = 0; @@ -326,11 +326,11 @@ void ripng_interface_clean(void) void ripng_interface_reset(void) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct ripng_interface *ri; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; ri->enable_network = 0; @@ -760,10 +760,10 @@ void ripng_enable_apply(struct interface *ifp) /* Set distribute list to all interfaces. */ static void ripng_enable_apply_all(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ripng_enable_apply(ifp); } @@ -821,10 +821,10 @@ void ripng_passive_interface_apply(struct interface *ifp) static void ripng_passive_interface_apply_all(void) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ripng_passive_interface_apply(ifp); } @@ -1069,12 +1069,12 @@ static int ripng_if_delete_hook(struct interface *ifp) /* Configuration write function for ripngd. */ static int interface_config_write(struct vty *vty) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct ripng_interface *ri; int write = 0; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; /* Do not display the interface if there is no diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c index 75b3c9dfec..2e0841c5d4 100644 --- a/ripngd/ripng_nexthop.c +++ b/ripngd/ripng_nexthop.c @@ -72,7 +72,7 @@ struct list *ripng_rte_new(void) void ripng_rte_free(struct list *ripng_rte_list) { - list_delete(ripng_rte_list); + list_delete_and_null(&ripng_rte_list); } /* Delete RTE */ diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c index efbdc1ffe8..82f8a7aa66 100644 --- a/ripngd/ripng_offset.c +++ b/ripngd/ripng_offset.c @@ -375,7 +375,7 @@ void ripng_offset_init(void) void ripng_offset_clean(void) { - list_delete(ripng_offset_list_master); + list_delete_and_null(&ripng_offset_list_master); ripng_offset_list_master = list_new(); ripng_offset_list_master->cmp = diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index e4368c9f9f..df3af2a17f 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -407,8 +407,7 @@ static int ripng_garbage_collect(struct thread *t) /* Unlock route_node. */ listnode_delete(rp->info, rinfo); if (list_isempty((struct list *)rp->info)) { - list_free(rp->info); - rp->info = NULL; + list_delete_and_null((struct list **)&rp->info); route_unlock_node(rp); } @@ -843,6 +842,8 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, unusable). */ if (rte->metric != RIPNG_METRIC_INFINITY) ripng_ecmp_add(&newinfo); + else + route_unlock_node(rp); } else { /* If there is an existing route, compare the next hop address to the address of the router from which the datagram came. @@ -1378,7 +1379,7 @@ static void ripng_clear_changed_flag(void) enabled interface. */ static int ripng_update(struct thread *t) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct ripng_interface *ri; @@ -1390,7 +1391,7 @@ static int ripng_update(struct thread *t) zlog_debug("RIPng update timer expired!"); /* Supply routes to each interface. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; if (if_is_loopback(ifp) || !if_is_up(ifp)) @@ -1446,7 +1447,7 @@ static int ripng_triggered_interval(struct thread *t) /* Execute triggered update. */ int ripng_triggered_update(struct thread *t) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; struct ripng_interface *ri; int interval; @@ -1466,7 +1467,7 @@ int ripng_triggered_update(struct thread *t) /* Split Horizon processing is done when generating triggered updates as well as normal updates (see section 2.6). */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; if (if_is_loopback(ifp) || !if_is_up(ifp)) @@ -2011,7 +2012,7 @@ DEFUN (show_ipv6_ripng, len = 28 - len; if (len > 0) - len = vty_out(vty, "%*s", len, " "); + vty_out(vty, "%*s", len, " "); /* from */ if ((rinfo->type == ZEBRA_ROUTE_RIPNG) @@ -2059,7 +2060,7 @@ DEFUN (show_ipv6_ripng_status, "Show RIPng routes\n" "IPv6 routing protocol process parameters and statistics\n") { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; if (!ripng) @@ -2092,7 +2093,7 @@ DEFUN (show_ipv6_ripng_status, vty_out(vty, " Interface Send Recv\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct ripng_interface *ri; ri = ifp->info; @@ -2150,7 +2151,7 @@ DEFUN (clear_ipv6_rip, } if (list_isempty(list)) { - list_free(list); + list_delete_and_null(&list); rp->info = NULL; route_unlock_node(rp); } @@ -2792,10 +2793,10 @@ void ripng_distribute_update_interface(struct interface *ifp) /* Update all interface's distribute list. */ static void ripng_distribute_update_all(struct prefix_list *notused) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ripng_distribute_update_interface(ifp); } @@ -2829,7 +2830,7 @@ void ripng_clean() rinfo->t_garbage_collect); ripng_info_free(rinfo); } - list_delete(list); + list_delete_and_null(&list); rp->info = NULL; route_unlock_node(rp); } @@ -2969,10 +2970,10 @@ static void ripng_routemap_update_redistribute(void) static void ripng_routemap_update(const char *unused) { + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) ripng_if_rmap_update_interface(ifp); ripng_routemap_update_redistribute(); diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index e61e9639ee..1f5abba392 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -166,7 +166,7 @@ static int test(FILE *input, FILE *output) sbuf_push(&fragment_format, 0, "%s", isis_format_tlvs(tlvs)); isis_free_tlvs(tlvs); } - list_delete(fragments); + list_delete_and_null(&fragments); stream_free(s); char *fragment_content = sortlines((char *)sbuf_buf(&fragment_format)); diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf index 6b341f5161..2d3b884e7e 100644 --- a/tools/etc/iproute2/rt_protos.d/frr.conf +++ b/tools/etc/iproute2/rt_protos.d/frr.conf @@ -8,4 +8,3 @@ 191 nhrp 192 eigrp 193 ldp -194 babel @@ -544,14 +544,22 @@ case "$1" in if [ -z "$dmn" -o "$dmn" = "zebra" ]; then echo "Removing all routes made by FRR." - ip route flush proto bgp - ip route flush proto ospf - ip route flush proto static - ip route flush proto rip - ip route flush proto ripng - ip route flush proto zebra - ip route flush proto isis - + # Specific values for each proto can be found + # in /etc/iproute2/rt_protos as well as FRR + # specific ones in /etc/iproute2/rt_protos.d + # Additionally if a new protocol is added + # we need to add it here as well as + # in rt_netlink.h( follow the directions! ) + ip route flush proto 186 + ip route flush proto 188 + ip route flush proto 4 + ip route flush proto 189 + ip route flush proto 190 + ip route flush proto 11 + ip route flush proto 187 + ip route flush proto 192 + ip route flush proto 42 + ip route flush proto 191 else [ -n "$dmn" ] && eval "${dmn/-/_}=0" start_watchfrr diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index d7e79d6b2c..138a446321 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -73,7 +73,7 @@ static int config_cmp(struct config *c1, struct config *c2) static void config_del(struct config *config) { - list_delete(config->line); + list_delete_and_null(&config->line); if (config->name) XFREE(MTYPE_VTYSH_CONFIG_LINE, config->name); XFREE(MTYPE_VTYSH_CONFIG, config); @@ -131,6 +131,20 @@ static void config_add_line_uniq(struct list *config, const char *line) listnode_add_sort(config, XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line)); } +/* + * I want to explicitly move this command to the end of the line + */ +static void config_add_line_end(struct list *config, const char *line) +{ + struct listnode *node; + void *item = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line); + + listnode_add(config, item); + node = listnode_lookup(config, item); + if (node) + listnode_move_to_tail(config, node); +} + void vtysh_config_parse_line(void *arg, const char *line) { char c; @@ -161,6 +175,10 @@ void vtysh_config_parse_line(void *arg, const char *line) == 0) { config_add_line(config->line, line); config->index = LINK_PARAMS_NODE; + } else if (strncmp(line, + " ip multicast boundary", + strlen(" ip multicast boundary")) == 0) { + config_add_line_end(config->line, line); } else if (config->index == LINK_PARAMS_NODE && strncmp(line, " exit-link-params", strlen(" exit")) @@ -365,7 +383,7 @@ void vtysh_config_dump(FILE *fp) for (i = 0; i < vector_active(configvec); i++) if ((master = vector_slot(configvec, i)) != NULL) { - list_delete(master); + list_delete_and_null(&master); vector_slot(configvec, i) = NULL; } list_delete_all_node(config_top); diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 99c05ef79b..8509a8a05a 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -451,7 +451,7 @@ int main(int argc, char **argv, char **env) exit(ret); } - if (dryrun && cmd) { + if (dryrun && cmd && cmd->line) { vtysh_execute("enable"); while (cmd) { struct cmd_rec *cr; @@ -552,7 +552,7 @@ int main(int argc, char **argv, char **env) } /* If eval mode. */ - if (cmd) { + if (cmd && cmd->line) { /* Enter into enable node. */ vtysh_execute("enable"); diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c index 6396911e1b..1d108886de 100644 --- a/zebra/if_ioctl.c +++ b/zebra/if_ioctl.c @@ -105,10 +105,7 @@ static int interface_list_ioctl(void) unsigned int size; ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n); - ifp = if_get_by_name_len( - ifreq->ifr_name, - strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)), - VRF_DEFAULT, 0); + ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT, 0); if_add_update(ifp); size = ifreq->ifr_addr.sa_len; if (size < sizeof(ifreq->ifr_addr)) @@ -118,10 +115,7 @@ static int interface_list_ioctl(void) } #else for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) { - ifp = if_get_by_name_len( - ifreq->ifr_name, - strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)), - VRF_DEFAULT, 0); + ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT, 0); if_add_update(ifp); ifreq++; } @@ -137,7 +131,7 @@ end: /* Get interface's index by ioctl. */ static int if_get_index(struct interface *ifp) { - ifp->ifindex = if_nametoindex(ifp->name); + if_set_index(ifp, if_nametoindex(ifp->name)); return ifp->ifindex; } @@ -268,10 +262,10 @@ static int if_getaddrs(void) /* Fetch interface information via ioctl(). */ static void interface_info_ioctl() { - struct listnode *node, *nnode; + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if_get_index(ifp); #ifdef SIOCGIFHWADDR if_get_hwaddr(ifp); diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c index 9ec575b5b0..94738664b3 100644 --- a/zebra/if_ioctl_solaris.c +++ b/zebra/if_ioctl_solaris.c @@ -170,8 +170,7 @@ calculate_lifc_len: /* must hold privileges to enter here */ && (*(lifreq->lifr_name + normallen) != ':')) normallen++; - ifp = if_get_by_name_len(lifreq->lifr_name, normallen, - VRF_DEFAULT, 0); + ifp = if_get_by_name(lifreq->lifr_name, VRF_DEFAULT, 0); if (lifreq->lifr_addr.ss_family == AF_INET) ifp->flags |= IFF_IPV4; @@ -228,9 +227,9 @@ static int if_get_index(struct interface *ifp) /* OK we got interface index. */ #ifdef ifr_ifindex - ifp->ifindex = lifreq.lifr_ifindex; + if_set_index(ifp, lifreq.lifr_ifindex); #else - ifp->ifindex = lifreq.lifr_index; + if_set_index(ifp, lifreq.lifr_index); #endif return ifp->ifindex; } diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 5a42e0c8f1..a2235904c6 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -93,7 +93,7 @@ static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, if_delete_update(oifp); } } - ifp->ifindex = ifi_index; + if_set_index(ifp, ifi_index); } /* Utility function to parse hardware link-layer address and update ifp */ @@ -666,7 +666,7 @@ static int netlink_interface(struct sockaddr_nl *snl, struct nlmsghdr *h, link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]); /* Add interface. */ - ifp = if_get_by_name(name, vrf_id); + ifp = if_get_by_name(name, vrf_id, 0); set_ifindex(ifp, ifi->ifi_index, zns); ifp->flags = ifi->ifi_flags & 0x0000fffff; if (IS_ZEBRA_IF_VRF(ifp)) @@ -1121,7 +1121,7 @@ int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h, if (ifp == NULL) { /* unknown interface */ - ifp = if_get_by_name(name, vrf_id); + ifp = if_get_by_name(name, vrf_id, 0); } else { /* pre-configured interface, learnt now */ if (ifp->vrf_id != vrf_id) diff --git a/zebra/interface.c b/zebra/interface.c index 664e493d84..e912b2dcf8 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -64,7 +64,7 @@ static void zebra_if_node_destroy(route_table_delegate_t *delegate, struct route_node *node) { if (node->info) - list_delete(node->info); + list_delete_and_null((struct list **)&node->info); route_node_destroy(delegate, table, node); } @@ -138,7 +138,7 @@ static int if_zebra_delete_hook(struct interface *ifp) struct rtadvconf *rtadv; rtadv = &zebra_if->rtadv; - list_free(rtadv->AdvPrefixList); + list_delete_and_null(&rtadv->AdvPrefixList); #endif /* HAVE_RTADV */ XFREE(MTYPE_TMP, zebra_if); @@ -322,7 +322,7 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc) } /* Otherwise, free list and route node. */ - list_free(addr_list); + list_delete_and_null(&addr_list); rn->info = NULL; route_unlock_node(rn); @@ -627,7 +627,7 @@ static void if_delete_connected(struct interface *ifp) } /* Free chain list and respective route node. */ - list_delete(addr_list); + list_delete_and_null(&addr_list); rn->info = NULL; route_unlock_node(rn); } else if (cp.family == AF_INET6) { @@ -685,7 +685,7 @@ void if_delete_update(struct interface *ifp) while processing the deletion. Each client daemon is responsible for setting ifindex to IFINDEX_INTERNAL after processing the interface deletion message. */ - ifp->ifindex = IFINDEX_INTERNAL; + if_set_index(ifp, IFINDEX_INTERNAL); ifp->node = NULL; /* if the ifp is in a vrf, move it to default so vrf can be deleted if @@ -1317,7 +1317,7 @@ DEFUN (show_interface, "Interface status and configuration\n" VRF_CMD_HELP_STR) { - struct listnode *node; + struct vrf *vrf; struct interface *ifp; vrf_id_t vrf_id = VRF_DEFAULT; @@ -1327,7 +1327,8 @@ DEFUN (show_interface, VRF_GET_ID(vrf_id, argv[3]->arg); /* All interface print. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) + vrf = vrf_lookup_by_id(vrf_id); + FOR_ALL_INTERFACES (vrf, ifp) if_dump_vty(vty, ifp); return CMD_SUCCESS; @@ -1343,14 +1344,13 @@ DEFUN (show_interface_vrf_all, VRF_ALL_CMD_HELP_STR) { struct vrf *vrf; - struct listnode *node; struct interface *ifp; interface_update_stats(); /* All interface print. */ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) if_dump_vty(vty, ifp); return CMD_SUCCESS; @@ -1425,11 +1425,11 @@ DEFUN (show_interface_name_vrf_all, static void if_show_description(struct vty *vty, vrf_id_t vrf_id) { - struct listnode *node; + struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct interface *ifp; vty_out(vty, "Interface Status Protocol Description\n"); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { int len; len = vty_out(vty, "%s", ifp->name); @@ -1486,7 +1486,7 @@ DEFUN (show_interface_desc_vrf_all, struct vrf *vrf; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - if (!list_isempty(vrf->iflist)) { + if (!RB_EMPTY (if_name_head, &vrf->ifaces_by_name)) { vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id); if_show_description(vty, vrf->vrf_id); } @@ -2830,13 +2830,12 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp) static int if_config_write(struct vty *vty) { struct vrf *vrf; - struct listnode *node; struct interface *ifp; zebra_ptm_write(vty); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct zebra_if *if_data; struct listnode *addrnode; struct connected *ifc; diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 0df03860d0..8234ed6bdd 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -311,8 +311,7 @@ static void irdp_if_stop(struct interface *ifp) irdp_advert_off(ifp); - list_delete(irdp->AdvPrefList); - irdp->AdvPrefList = NULL; + list_delete_and_null(&irdp->AdvPrefList); irdp->flags = 0; } diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index bc85e983e7..5567d53c3f 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -315,7 +315,6 @@ void process_solicit(struct interface *ifp) static int irdp_finish(void) { struct vrf *vrf; - struct listnode *node, *nnode; struct interface *ifp; struct zebra_if *zi; struct irdp_interface *irdp; @@ -323,7 +322,7 @@ static int irdp_finish(void) zlog_info("IRDP: Received shutdown notification."); RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - for (ALL_LIST_ELEMENTS(vrf->iflist, node, nnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { zi = ifp->info; if (!zi) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 9907ef5b79..89c933f90f 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -323,11 +323,8 @@ static int ifan_read(struct if_announcemsghdr *ifan) __func__, ifan->ifan_index, ifan->ifan_name); /* Create Interface */ - ifp = if_get_by_name_len( - ifan->ifan_name, - strnlen(ifan->ifan_name, sizeof(ifan->ifan_name)), - VRF_DEFAULT, 0); - ifp->ifindex = ifan->ifan_index; + ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT, 0); + if_set_index(ifp, ifan->ifan_index); if_get_metric(ifp); if_add_update(ifp); @@ -517,7 +514,7 @@ int ifm_read(struct if_msghdr *ifm) if (ifp == NULL) { /* Interface that zebra was not previously aware of, so * create. */ - ifp = if_create(ifname, ifnlen, VRF_DEFAULT); + ifp = if_create(ifname, VRF_DEFAULT); if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("%s: creating ifp for ifindex %d", __func__, ifm->ifm_index); @@ -531,7 +528,7 @@ int ifm_read(struct if_msghdr *ifm) * Fill in newly created interface structure, or larval * structure with ifindex IFINDEX_INTERNAL. */ - ifp->ifindex = ifm->ifm_index; + if_set_index(ifp, ifm->ifm_index); #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */ bsd_linkdetect_translate(ifm); diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 1ed5eacd80..6fbb751789 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -375,5 +375,5 @@ int release_daemon_chunks(u_char proto, u_short instance) void label_manager_close() { - list_delete(lbl_mgr.lc_list); + list_delete_and_null(&lbl_mgr.lc_list); } diff --git a/zebra/main.c b/zebra/main.c index bf1971c470..5a2979c866 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -145,7 +145,7 @@ static void sigint(void) prefix_list_reset(); route_map_finish(); - list_delete(zebrad.client_list); + list_delete_and_null(&zebrad.client_list); work_queue_free(zebrad.ribq); if (zebrad.lsp_process_q) work_queue_free(zebrad.lsp_process_q); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 890ad887da..cc679142f7 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -519,32 +519,20 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, if (same) zebra_del_import_table_entry(rn, same); - if (re->nexthop_num == 1) { - rib_add(afi, SAFI_UNICAST, re->vrf_id, - ZEBRA_ROUTE_TABLE, re->table, 0, &p, - NULL, re->nexthop, - zebrad.rtm_table_default, re->metric, - re->mtu, - zebra_import_table_distance[afi] - [re->table]); - } else if (re->nexthop_num > 1) { - newre = XCALLOC(MTYPE_RE, - sizeof(struct route_entry)); - newre->type = ZEBRA_ROUTE_TABLE; - newre->distance = - zebra_import_table_distance[afi][re->table]; - newre->flags = re->flags; - newre->metric = re->metric; - newre->mtu = re->mtu; - newre->table = zebrad.rtm_table_default; - newre->nexthop_num = 0; - newre->uptime = time(NULL); - newre->instance = re->table; - route_entry_copy_nexthops(newre, re->nexthop); - - rib_add_multipath(afi, SAFI_UNICAST, &p, - NULL, newre); - } + newre = XCALLOC(MTYPE_RE,sizeof(struct route_entry)); + newre->type = ZEBRA_ROUTE_TABLE; + newre->distance = zebra_import_table_distance[afi][re->table]; + newre->flags = re->flags; + newre->metric = re->metric; + newre->mtu = re->mtu; + newre->table = zebrad.rtm_table_default; + newre->nexthop_num = 0; + newre->uptime = time(NULL); + newre->instance = re->table; + route_entry_copy_nexthops(newre, re->nexthop); + + rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre); + return 0; } @@ -557,7 +545,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) prefix_copy(&p, &rn->p); rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, - re->table, re->flags, &p, NULL, NULL, + re->table, re->flags, &p, NULL, re->nexthop, zebrad.rtm_table_default, re->metric, false); return 0; diff --git a/zebra/rib.h b/zebra/rib.h index e3ed6210ca..61beebb409 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -71,7 +71,7 @@ struct route_entry { u_int32_t nexthop_mtu; /* Distance. */ - u_char distance; + uint8_t distance; /* Flags of this route. * This flag's definition is in lib/zebra.h ZEBRA_FLAG_* and is exposed @@ -296,7 +296,7 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, - u_char distance); + uint8_t distance); extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, struct prefix_ipv6 *src_p, struct route_entry *); @@ -330,7 +330,7 @@ extern void rib_unlink(struct route_node *, struct route_entry *); extern int rib_gc_dest(struct route_node *rn); extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter); -extern u_char route_distance(int type); +extern uint8_t route_distance(int type); /* * Inline functions. diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 573f60f4ca..0cc2e0217f 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -267,7 +267,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, struct rtattr *tb[RTA_MAX + 1]; u_char flags = 0; struct prefix p; - struct prefix_ipv6 src_p; + struct prefix_ipv6 src_p = {}; vrf_id_t vrf_id = VRF_DEFAULT; char anyaddr[16] = {0}; @@ -277,6 +277,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, int table; int metric = 0; u_int32_t mtu = 0; + uint8_t distance = 0; void *dest = NULL; void *gate = NULL; @@ -405,16 +406,38 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, return 0; } + /* + * For ZEBRA_ROUTE_KERNEL types: + * + * The metric/priority of the route received from the kernel + * is a 32 bit number. We are going to interpret the high + * order byte as the Admin Distance and the low order 3 bytes + * as the metric. + * + * This will allow us to do two things: + * 1) Allow the creation of kernel routes that can be + * overridden by zebra. + * 2) Allow the old behavior for 'most' kernel route types + * if a user enters 'ip route ...' v4 routes get a metric + * of 0 and v6 routes get a metric of 1024. Both of these + * values will end up with a admin distance of 0, which + * will cause them to win for the purposes of zebra. + */ + if (proto == ZEBRA_ROUTE_KERNEL) { + distance = (metric >> 24) & 0xFF; + metric = (metric & 0x00FFFFFF); + } + if (IS_ZEBRA_DEBUG_KERNEL) { char buf[PREFIX_STRLEN]; char buf2[PREFIX_STRLEN]; zlog_debug( - "%s %s%s%s vrf %u", nl_msg_type_to_str(h->nlmsg_type), + "%s %s%s%s vrf %u metric: %d Admin Distance: %d", nl_msg_type_to_str(h->nlmsg_type), prefix2str(&p, buf, sizeof(buf)), src_p.prefixlen ? " from " : "", src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "", - vrf_id); + vrf_id, metric, distance); } afi_t afi = AFI_IP; @@ -454,7 +477,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, memcpy(&nh.gate, gate, sz); rib_add(afi, SAFI_UNICAST, vrf_id, proto, - 0, flags, &p, NULL, &nh, table, metric, mtu, 0); + 0, flags, &p, NULL, &nh, table, metric, mtu, distance); } else { /* This is a multipath route */ @@ -466,7 +489,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); re->type = proto; - re->distance = 0; + re->distance = distance; re->flags = flags; re->metric = metric; re->mtu = mtu; @@ -822,7 +845,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, { struct nexthop_label *nh_label; mpls_lse_t out_lse[MPLS_MAX_LABELS]; - char label_buf[100]; + char label_buf[256]; /* * label_buf is *only* currently used within debugging. @@ -853,12 +876,13 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, 0, 0, bos); if (IS_ZEBRA_DEBUG_KERNEL) { if (!num_labels) - sprintf(label_buf, "label %d", + sprintf(label_buf, "label %u", nh_label->label[i]); else { - sprintf(label_buf1, "/%d", + sprintf(label_buf1, "/%u", nh_label->label[i]); - strcat(label_buf, label_buf1); + strlcat(label_buf, label_buf1, + sizeof(label_buf)); } } num_labels++; @@ -1021,7 +1045,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, { struct nexthop_label *nh_label; mpls_lse_t out_lse[MPLS_MAX_LABELS]; - char label_buf[100]; + char label_buf[256]; rtnh->rtnh_len = sizeof(*rtnh); rtnh->rtnh_flags = 0; @@ -1057,12 +1081,13 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, 0, 0, bos); if (IS_ZEBRA_DEBUG_KERNEL) { if (!num_labels) - sprintf(label_buf, "label %d", + sprintf(label_buf, "label %u", nh_label->label[i]); else { - sprintf(label_buf1, "/%d", + sprintf(label_buf1, "/%u", nh_label->label[i]); - strcat(label_buf, label_buf1); + strlcat(label_buf, label_buf1, + sizeof(label_buf)); } } num_labels++; @@ -1716,7 +1741,6 @@ static int netlink_macfdb_change(struct sockaddr_nl *snl, struct nlmsghdr *h, struct ndmsg *ndm; struct interface *ifp; struct zebra_if *zif; - struct zebra_vrf *zvrf; struct rtattr *tb[NDA_MAX + 1]; struct interface *br_if; struct ethaddr mac; @@ -1730,20 +1754,14 @@ static int netlink_macfdb_change(struct sockaddr_nl *snl, struct nlmsghdr *h, ndm = NLMSG_DATA(h); + /* We only process macfdb notifications if EVPN is enabled */ + if (!is_evpn_enabled()) + return 0; + /* The interface should exist. */ ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ndm->ndm_ifindex); - if (!ifp) - return 0; - - /* Locate VRF corresponding to interface. We only process MAC - * notifications - * if EVPN is enabled on this VRF. - */ - zvrf = vrf_info_lookup(ifp->vrf_id); - if (!zvrf || !EVPN_ENABLED(zvrf)) - return 0; - if (!ifp->info) + if (!ifp || !ifp->info) return 0; /* The interface should be something we're interested in. */ @@ -2033,7 +2051,6 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h, struct ndmsg *ndm; struct interface *ifp; struct zebra_if *zif; - struct zebra_vrf *zvrf; struct rtattr *tb[NDA_MAX + 1]; struct interface *link_if; struct ethaddr mac; @@ -2045,20 +2062,14 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h, ndm = NLMSG_DATA(h); + /* We only process neigh notifications if EVPN is enabled */ + if (!is_evpn_enabled()) + return 0; + /* The interface should exist. */ ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ndm->ndm_ifindex); - if (!ifp) - return 0; - - /* Locate VRF corresponding to interface. We only process neigh - * notifications - * if EVPN is enabled on this VRF. - */ - zvrf = vrf_info_lookup(ifp->vrf_id); - if (!zvrf || !EVPN_ENABLED(zvrf)) - return 0; - if (!ifp->info) + if (!ifp || !ifp->info) return 0; /* Drop "permanent" entries. */ diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index e607dda6f9..980ff915cc 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -27,14 +27,26 @@ #define NL_DEFAULT_ROUTE_METRIC 20 -/* Additional protocol strings to push into routes */ +/* + * Additional protocol strings to push into routes + * If we add anything new here please make sure + * to update: + * zebra2proto Function + * proto2zebra Function + * is_selfroute Function + * tools/frr To flush the route upon exit + * + * Finally update this file to allow iproute2 to + * know about this new route. + * tools/etc/iproute2/rt_protos.d + */ #define RTPROT_BGP 186 #define RTPROT_ISIS 187 #define RTPROT_OSPF 188 #define RTPROT_RIP 189 #define RTPROT_RIPNG 190 #if !defined(RTPROT_BABEL) -#define RTPROT_BABEL 42 +#define RTPROT_BABEL 42 #endif #define RTPROT_NHRP 191 #define RTPROT_EIGRP 192 diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 633604120c..6a8e2ac594 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -383,7 +383,6 @@ static int rtadv_timer(struct thread *thread) { struct zebra_ns *zns = THREAD_ARG(thread); struct vrf *vrf; - struct listnode *node, *nnode; struct interface *ifp; struct zebra_if *zif; int period; @@ -398,7 +397,7 @@ static int rtadv_timer(struct thread *thread) } RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - for (ALL_LIST_ELEMENTS(vrf->iflist, node, nnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { if (if_is_loopback(ifp) || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 345637c044..529fc48edf 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -52,11 +52,10 @@ static void map_slaves_to_bridge(struct interface *br_if, int link) { struct vrf *vrf; - struct listnode *node; struct interface *ifp; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { struct zebra_if *zif; struct zebra_l2info_brslave *br_slave; diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 3c7319f35d..7b87355ed4 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -554,7 +554,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p, */ static int fec_del(zebra_fec_t *fec) { - list_free(fec->client_list); + list_delete_and_null(&fec->client_list); fec->rn->info = NULL; route_unlock_node(fec->rn); XFREE(MTYPE_FEC, fec); @@ -2701,7 +2701,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "\n"); } - list_delete(lsp_list); + list_delete_and_null(&lsp_list); } /* @@ -2740,7 +2740,7 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) } } - list_delete(slsp_list); + list_delete_and_null(&slsp_list); return (zvrf->slsp_table->count ? 1 : 0); } diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index a42e6680e8..93b0723d8b 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -257,14 +257,13 @@ DEFUN (zebra_ptm_enable, "Enable neighbor check with specified topology\n") { struct vrf *vrf; - struct listnode *i; struct interface *ifp; struct zebra_if *if_data; ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, i, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) if (!ifp->ptm_enable) { if_data = (struct zebra_if *)ifp->info; if (if_data @@ -1088,12 +1087,11 @@ void zebra_ptm_send_status_req(void) void zebra_ptm_reset_status(int ptm_disable) { struct vrf *vrf; - struct listnode *i; struct interface *ifp; int send_linkup; RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, i, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { send_linkup = 0; if (ifp->ptm_enable) { if (!if_is_operative(ifp)) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index fab8c3c932..d46e0730ee 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -129,9 +129,9 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, #define rnode_info(node, ...) \ _rnode_zlog(__func__, vrf_id, node, LOG_INFO, __VA_ARGS__) -u_char route_distance(int type) +uint8_t route_distance(int type) { - u_char distance; + uint8_t distance; if ((unsigned)type >= array_size(route_info)) distance = 150; @@ -325,9 +325,11 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, resolved_hop = nexthop_new(); SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); - /* If the resolving route specifies a gateway, use it */ - if (newhop->type == NEXTHOP_TYPE_IPV4 - || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { + + switch (newhop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + /* If the resolving route specifies a gateway, use it */ resolved_hop->type = newhop->type; resolved_hop->gate.ipv4 = newhop->gate.ipv4; @@ -337,9 +339,9 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, if (newhop->flags & NEXTHOP_FLAG_ONLINK) resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; } - } - if (newhop->type == NEXTHOP_TYPE_IPV6 - || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: resolved_hop->type = newhop->type; resolved_hop->gate.ipv6 = newhop->gate.ipv6; @@ -347,18 +349,17 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; resolved_hop->ifindex = newhop->ifindex; } - } - - /* If the resolving route is an interface route, - * it means the gateway we are looking up is connected - * to that interface. (The actual network is _not_ onlink). - * Therefore, the resolved route should have the original - * gateway as nexthop as it is directly connected. - * - * On Linux, we have to set the onlink netlink flag because - * otherwise, the kernel won't accept the route. - */ - if (newhop->type == NEXTHOP_TYPE_IFINDEX) { + break; + case NEXTHOP_TYPE_IFINDEX: + /* If the resolving route is an interface route, + * it means the gateway we are looking up is connected + * to that interface. (The actual network is _not_ onlink). + * Therefore, the resolved route should have the original + * gateway as nexthop as it is directly connected. + * + * On Linux, we have to set the onlink netlink flag because + * otherwise, the kernel won't accept the route. + */ resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; if (afi == AFI_IP) { resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; @@ -368,12 +369,13 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, resolved_hop->gate.ipv6 = nexthop->gate.ipv6; } resolved_hop->ifindex = newhop->ifindex; - } - - if (newhop->type == NEXTHOP_TYPE_BLACKHOLE) { + break; + case NEXTHOP_TYPE_BLACKHOLE: resolved_hop->type = NEXTHOP_TYPE_BLACKHOLE; resolved_hop->bh_type = nexthop->bh_type; + break; } + resolved_hop->rparent = nexthop; nexthop_add(&nexthop->resolved, resolved_hop); } @@ -1875,7 +1877,7 @@ void meta_queue_free(struct meta_queue *mq) unsigned i; for (i = 0; i < MQ_SIZE; i++) - list_delete(mq->subq[i]); + list_delete_and_null(&mq->subq[i]); XFREE(MTYPE_WORK_QUEUE, mq); } @@ -2463,7 +2465,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, - u_int32_t mtu, u_char distance) + u_int32_t mtu, uint8_t distance) { struct route_entry *re; struct nexthop *nexthop; diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index fabb4f9e14..355fef94f4 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -160,9 +160,9 @@ struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type) void zebra_free_rnh(struct rnh *rnh) { rnh->flags |= ZEBRA_NHT_DELETED; - list_free(rnh->client_list); - list_free(rnh->zebra_static_route_list); - list_free(rnh->zebra_pseudowire_list); + list_delete_and_null(&rnh->client_list); + list_delete_and_null(&rnh->zebra_static_route_list); + list_delete_and_null(&rnh->zebra_pseudowire_list); free_state(rnh->vrf_id, rnh->state, rnh->node); XFREE(MTYPE_RNH, rnh); } diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index bf8a17c3ef..0d0a8dd747 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -179,7 +179,6 @@ static int zebra_vrf_delete(struct vrf *vrf) /* uninstall everything */ if (!CHECK_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN)) { - struct listnode *node; struct interface *ifp; for (afi = AFI_IP; afi <= AFI_IP6; afi++) { @@ -204,7 +203,7 @@ static int zebra_vrf_delete(struct vrf *vrf) zebra_mpls_close_tables(zvrf); zebra_pw_exit(zvrf); - for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) + FOR_ALL_INTERFACES (vrf, ifp) if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 6e2dc613df..1dfc0b3eb8 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -102,13 +102,15 @@ struct zebra_vrf { * VNI hash table (for EVPN). Only in default instance. */ struct hash *vni_table; + /* - * Whether EVPN is enabled or not. + * Whether EVPN is enabled or not. Only in default instance. */ int advertise_all_vni; /* * Whether we are advertising g/w macip in EVPN or not. + * Only in default instance. */ int advertise_gw_macip; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 04cd17cedb..d86cc88b42 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -455,7 +455,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, vty_out(vty, ", distance %u, metric %u", re->distance, re->metric); if (re->tag) - vty_out(vty, ", tag %d", re->tag); + vty_out(vty, ", tag %u", re->tag); if (re->mtu) vty_out(vty, ", mtu %u", re->mtu); if (re->vrf_id != VRF_DEFAULT) { @@ -829,7 +829,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, /* Distance and metric display. */ if (re->type != ZEBRA_ROUTE_CONNECT) - len += vty_out(vty, " [%d/%d]", re->distance, + len += vty_out(vty, " [%u/%u]", re->distance, re->metric); } else { vty_out(vty, " %c%*c", diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index a3f43f947a..c0b5f9d10f 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -67,7 +67,7 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt); static void zvni_print(zebra_vni_t *zvni, void **ctxt); static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]); -static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, struct ipaddr *ip, u_char flags, u_int16_t cmd); @@ -80,20 +80,20 @@ static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n); static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg); static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall, struct in_addr *r_vtep_ip); -static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni, +static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, u_int32_t flags); static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip); -static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, u_char flags); -static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, u_char flags); static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n); static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n); static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if); -static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid, +static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if); static unsigned int mac_hash_keymake(void *p); @@ -104,12 +104,12 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac); static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg); static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall, struct in_addr *r_vtep_ip); -static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni, +static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, u_int32_t flags); static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr); -static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, u_char flags); -static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, u_char flags); static zebra_vni_t *zvni_map_vlan(struct interface *ifp, struct interface *br_if, vlanid_t vid); @@ -120,12 +120,12 @@ static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt); static unsigned int vni_hash_keymake(void *p); static int vni_hash_cmp(const void *p1, const void *p2); static void *zvni_alloc(void *p); -static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni); -static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni); -static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni); -static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni); -static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni); -static void zvni_build_hash_table(struct zebra_vrf *zvrf); +static zebra_vni_t *zvni_lookup(vni_t vni); +static zebra_vni_t *zvni_add(vni_t vni); +static int zvni_del(zebra_vni_t *zvni); +static int zvni_send_add_to_client(zebra_vni_t *zvni); +static int zvni_send_del_to_client(vni_t vni); +static void zvni_build_hash_table(); static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep); static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip); static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip); @@ -140,15 +140,44 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, struct ipaddr *ip); struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp); -static int advertise_gw_macip_enabled(struct zebra_vrf *zvrf, - zebra_vni_t *zvni); +static int advertise_gw_macip_enabled(zebra_vni_t *zvni); static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac, int uninstall); /* Private functions */ -static int advertise_gw_macip_enabled(struct zebra_vrf *zvrf, zebra_vni_t *zvni) +/* + * Return number of valid MACs in a VNI's MAC hash table - all + * remote MACs and non-internal (auto) local MACs count. + */ +static u_int32_t num_valid_macs(zebra_vni_t *zvni) { + unsigned int i; + u_int32_t num_macs = 0; + struct hash *hash; + struct hash_backet *hb; + zebra_mac_t *mac; + + hash = zvni->mac_table; + if (!hash) + return num_macs; + for (i = 0; i < hash->size; i++) { + for (hb = hash->index[i]; hb; hb = hb->next) { + mac = (zebra_mac_t *)hb->data; + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) + || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) + num_macs++; + } + } + + return num_macs; +} + +static int advertise_gw_macip_enabled(zebra_vni_t *zvni) +{ + struct zebra_vrf *zvrf; + + zvrf = vrf_info_lookup(VRF_DEFAULT); if (zvrf && zvrf->advertise_gw_macip) return 1; @@ -541,7 +570,7 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt) /*We are iterating over a new VNI, set the count to 0*/ wctx->count = 0; - num_macs = hashcount(zvni->mac_table); + num_macs = num_valid_macs(zvni); if (!num_macs) return; @@ -600,7 +629,7 @@ static void zvni_print(zebra_vni_t *zvni, void **ctxt) vty_out(vty, " VxLAN interface: unknown\n"); return; } - num_macs = hashcount(zvni->mac_table); + num_macs = num_valid_macs(zvni); num_neigh = hashcount(zvni->neigh_table); if (json == NULL) vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n", @@ -682,7 +711,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]) zvtep = zvtep->next; } - num_macs = hashcount(zvni->mac_table); + num_macs = num_valid_macs(zvni); num_neigh = hashcount(zvni->neigh_table); if (json == NULL) vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni->vni, @@ -719,7 +748,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]) /* * Inform BGP about local MACIP. */ -static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, struct ipaddr *ip, u_char flags, u_int16_t cmd) @@ -738,7 +767,7 @@ static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni, s = client->obuf; stream_reset(s); - zserv_create_header(s, cmd, zvrf_id(zvrf)); + zserv_create_header(s, cmd, VRF_DEFAULT); stream_putl(s, vni); stream_put(s, macaddr->octet, ETH_ALEN); if (ip) { @@ -761,8 +790,8 @@ static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s", - zvrf_id(zvrf), (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", + "Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s", + (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags, prefix_mac2str(macaddr, buf, sizeof(buf)), ipaddr2str(ip, buf2, sizeof(buf2)), vni, zebra_route_string(client->proto)); @@ -882,8 +911,7 @@ static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg) && (n->flags & ZEBRA_NEIGH_REMOTE) && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) { if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL)) - zvni_neigh_send_del_to_client(wctx->zvrf, - wctx->zvni->vni, &n->ip, + zvni_neigh_send_del_to_client(wctx->zvni->vni, &n->ip, &n->emac, 0); if (wctx->uninstall) @@ -921,7 +949,7 @@ static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall, /* * Delete all neighbor entries for this VNI. */ -static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni, +static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, u_int32_t flags) { struct neigh_walk_ctx wctx; @@ -931,7 +959,6 @@ static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni, memset(&wctx, 0, sizeof(struct neigh_walk_ctx)); wctx.zvni = zvni; - wctx.zvrf = zvrf; wctx.uninstall = uninstall; wctx.upd_client = upd_client; wctx.flags = flags; @@ -958,8 +985,7 @@ static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip) } /* Process all neigh associated to a mac upon local mac add event */ -static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf, - zebra_vni_t *zvni, +static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; @@ -974,8 +1000,7 @@ static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf, if (IS_ZEBRA_NEIGH_INACTIVE(n)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u: neigh %s (MAC %s) on VNI %u is now ACTIVE", - zvrf_id(zvrf), + "neigh %s (MAC %s) on VNI %u is now ACTIVE", ipaddr2str(&n->ip, buf2, sizeof(buf2)), prefix_mac2str(&n->emac, buf, @@ -984,12 +1009,11 @@ static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf, ZEBRA_NEIGH_SET_ACTIVE(n); zvni_neigh_send_add_to_client( - zvrf, zvni->vni, &n->ip, &n->emac, 0); + zvni->vni, &n->ip, &n->emac, 0); } else { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u: neigh %s (MAC %s) on VNI %u should NOT be ACTIVE", - zvrf_id(zvrf), + "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE", ipaddr2str(&n->ip, buf2, sizeof(buf2)), prefix_mac2str(&n->emac, buf, @@ -1003,8 +1027,7 @@ static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf, } /* Process all neigh associated to a mac upon local mac del event */ -static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf, - zebra_vni_t *zvni, +static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; @@ -1017,8 +1040,7 @@ static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf, if (IS_ZEBRA_NEIGH_ACTIVE(n)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u: neigh %s (MAC %s) on VNI %u is now INACTIVE", - zvrf_id(zvrf), + "neigh %s (MAC %s) on VNI %u is now INACTIVE", ipaddr2str(&n->ip, buf2, sizeof(buf2)), prefix_mac2str(&n->emac, buf, @@ -1027,13 +1049,12 @@ static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf, ZEBRA_NEIGH_SET_INACTIVE(n); zvni_neigh_send_del_to_client( - zvrf, zvni->vni, &n->ip, &n->emac, 0); + zvni->vni, &n->ip, &n->emac, 0); } } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_err( - "%u: local MAC %s getting deleted on VNI %u has remote neigh %s", - zvrf_id(zvrf), + "local MAC %s getting deleted on VNI %u has remote neigh %s", prefix_mac2str(&n->emac, buf, sizeof(buf)), zvni->vni, @@ -1043,8 +1064,7 @@ static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf, } /* process all neigh associated to a mac entry upon remote mac add */ -static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf, - zebra_vni_t *zvni, +static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; @@ -1057,8 +1077,7 @@ static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf, if (IS_ZEBRA_NEIGH_ACTIVE(n)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u: neigh %s (MAC %s) on VNI %u INACTIVE", - zvrf_id(zvrf), + "neigh %s (MAC %s) on VNI %u INACTIVE", ipaddr2str(&n->ip, buf2, sizeof(buf2)), prefix_mac2str(&n->emac, buf, @@ -1067,15 +1086,14 @@ static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf, ZEBRA_NEIGH_SET_INACTIVE(n); zvni_neigh_send_del_to_client( - zvrf, zvni->vni, &n->ip, &n->emac, 0); + zvni->vni, &n->ip, &n->emac, 0); } } } } /* process all neigh associated to mac entry upon remote mac del */ -static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf, - zebra_vni_t *zvni, +static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; @@ -1087,8 +1105,7 @@ static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf, if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_err( - "%u: remote MAC %s getting deleted on VNI %u has local neigh %s", - zvrf_id(zvrf), + "remote MAC %s getting deleted on VNI %u has local neigh %s", prefix_mac2str(&n->emac, buf, sizeof(buf)), zvni->vni, @@ -1100,22 +1117,22 @@ static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf, /* * Inform BGP about local neighbor addition. */ -static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, u_char flags) { - return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, flags, + return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags, ZEBRA_MACIP_ADD); } /* * Inform BGP about local neighbor deletion. */ -static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, u_char flags) { - return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, flags, + return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags, ZEBRA_MACIP_DEL); } @@ -1124,7 +1141,6 @@ static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni, */ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n) { - struct zebra_vrf *zvrf; struct zebra_if *zif; struct zebra_l2info_vxlan *vxl; struct interface *vlan_if; @@ -1132,15 +1148,12 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n) if (!(n->flags & ZEBRA_NEIGH_REMOTE)) return 0; - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - assert(zvrf); zif = zvni->vxlan_if->info; if (!zif) return -1; vxl = &zif->l2info.vxl; - vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan, - zif->brslave_info.br_if); + vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); if (!vlan_if) return -1; @@ -1152,7 +1165,6 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n) */ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) { - struct zebra_vrf *zvrf; struct zebra_if *zif; struct zebra_l2info_vxlan *vxl; struct interface *vlan_if; @@ -1166,15 +1178,11 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) return -1; } - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - assert(zvrf); - zif = zvni->vxlan_if->info; if (!zif) return -1; vxl = &zif->l2info.vxl; - vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan, - zif->brslave_info.br_if); + vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); if (!vlan_if) return -1; @@ -1203,12 +1211,11 @@ struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp) struct zebra_vrf *zvrf = NULL; struct interface *tmp_if = NULL; struct zebra_if *zif = NULL; - struct listnode *node; zvrf = vrf_info_lookup(ifp->vrf_id); assert(zvrf); - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) { + FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) { zif = tmp_if->info; if (!zif) continue; @@ -1225,15 +1232,10 @@ struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp) static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni) { - struct zebra_vrf *zvrf = NULL; struct listnode *cnode = NULL, *cnnode = NULL; struct connected *c = NULL; struct ethaddr macaddr; - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - if (!zvrf) - return -1; - memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) { @@ -1263,15 +1265,10 @@ static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni) static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni) { - struct zebra_vrf *zvrf = NULL; struct listnode *cnode = NULL, *cnnode = NULL; struct connected *c = NULL; struct ethaddr macaddr; - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - if (!zvrf) - return -1; - memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) { @@ -1305,7 +1302,6 @@ static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni) static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, struct ethaddr *macaddr, struct ipaddr *ip) { - struct zebra_vrf *zvrf = NULL; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; zebra_neigh_t *n = NULL; @@ -1313,10 +1309,6 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - if (!zvrf) - return -1; - zif = zvni->vxlan_if->info; if (!zif) return -1; @@ -1327,8 +1319,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, if (!mac) { mac = zvni_mac_add(zvni, macaddr); if (!mac) { - zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u", - ifp->vrf_id, + zlog_err("Failed to add MAC %s intf %s(%u) VID %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vxl->access_vlan); return -1; @@ -1347,8 +1338,8 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, n = zvni_neigh_add(zvni, ip, macaddr); if (!n) { zlog_err( - "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), + "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", + ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, zvni->vni); return -1; @@ -1362,12 +1353,12 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP", - ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni, + "SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP", + ifp->name, ifp->ifindex, zvni->vni, prefix_mac2str(macaddr, buf, sizeof(buf)), ipaddr2str(ip, buf2, sizeof(buf2))); - zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, macaddr, + zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, ZEBRA_MAC_TYPE_GW); return 0; @@ -1379,16 +1370,11 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, struct ipaddr *ip) { - struct zebra_vrf *zvrf = NULL; zebra_neigh_t *n = NULL; zebra_mac_t *mac = NULL; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - if (!zvrf) - return -1; - /* If the neigh entry is not present nothing to do*/ n = zvni_neigh_lookup(zvni, ip); if (!n) @@ -1397,8 +1383,7 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, /* mac entry should be present */ mac = zvni_mac_lookup(zvni, &n->emac); if (!mac) { - zlog_err("%u: MAC %s doesnt exists for neigh %s on VNI %u", - ifp->vrf_id, + zlog_err("MAC %s doesnt exists for neigh %s on VNI %u", prefix_mac2str(&n->emac, buf1, sizeof(buf1)), ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni); return -1; @@ -1410,13 +1395,13 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP", - ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni, + "SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP", + ifp->name, ifp->ifindex, zvni->vni, prefix_mac2str(&(n->emac), buf1, sizeof(buf1)), ipaddr2str(ip, buf2, sizeof(buf2))); /* Remove neighbor from BGP. */ - zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac, + zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, ZEBRA_MAC_TYPE_GW); /* Delete this neighbor entry. */ @@ -1430,7 +1415,7 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, } static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet, - void *zvrf) + void *ctxt) { zebra_vni_t *zvni = NULL; struct zebra_if *zif = NULL; @@ -1455,8 +1440,7 @@ static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet, zl2_info = zif->l2info.vxl; - vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan, - zif->brslave_info.br_if); + vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if); if (!vlan_if) return; @@ -1472,7 +1456,7 @@ static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet, } static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet, - void *zvrf) + void *ctxt) { zebra_vni_t *zvni = NULL; struct zebra_if *zif = NULL; @@ -1485,7 +1469,7 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet, if (!zvni) return; - if (!advertise_gw_macip_enabled(zvrf, zvni)) + if (!advertise_gw_macip_enabled(zvni)) return; ifp = zvni->vxlan_if; @@ -1498,14 +1482,11 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet, return; zl2_info = zif->l2info.vxl; - vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan, + vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if); if (!vlan_if) return; - if (!advertise_gw_macip_enabled(zvrf, zvni)) - return; - /* Add primary SVI MAC-IP */ zvni_add_macip_for_intf(vlan_if, zvni); @@ -1587,7 +1568,7 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac) { zebra_mac_t *tmp_mac; - list_delete(mac->neigh_list); + list_delete_and_null(&mac->neigh_list); /* Free the VNI hash entry and allocated memory. */ tmp_mac = hash_release(zvni->mac_table, mac); @@ -1617,7 +1598,7 @@ static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg) sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0; zvni_mac_send_del_to_client( - wctx->zvrf, wctx->zvni->vni, &mac->macaddr, + wctx->zvni->vni, &mac->macaddr, (sticky ? ZEBRA_MAC_TYPE_STICKY : 0)); } @@ -1655,7 +1636,7 @@ static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall, /* * Delete all MAC entries for this VNI. */ -static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni, +static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, u_int32_t flags) { struct mac_walk_ctx wctx; @@ -1665,7 +1646,6 @@ static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni, memset(&wctx, 0, sizeof(struct mac_walk_ctx)); wctx.zvni = zvni; - wctx.zvrf = zvrf; wctx.uninstall = uninstall; wctx.upd_client = upd_client; wctx.flags = flags; @@ -1693,43 +1673,39 @@ static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac) /* * Inform BGP about local MAC addition. */ -static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, u_char flags) { - return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, flags, + return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags, ZEBRA_MACIP_ADD); } /* * Inform BGP about local MAC deletion. */ -static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni, +static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, u_char flags) { - return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, flags, + return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags, ZEBRA_MACIP_DEL); } /* * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC - * notifications, to see if there are of interest. - * TODO: Need to make this as a hash table. + * notifications, to see if they are of interest. */ static zebra_vni_t *zvni_map_vlan(struct interface *ifp, struct interface *br_if, vlanid_t vid) { - struct zebra_vrf *zvrf; - struct listnode *node; - struct interface *tmp_if; + struct zebra_ns *zns; + struct route_node *rn; + struct interface *tmp_if = NULL; struct zebra_if *zif; struct zebra_l2info_bridge *br; - struct zebra_l2info_vxlan *vxl; + struct zebra_l2info_vxlan *vxl = NULL; u_char bridge_vlan_aware; zebra_vni_t *zvni; - - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); + int found = 0; /* Determine if bridge is VLAN-aware or not */ zif = br_if->info; @@ -1739,7 +1715,11 @@ static zebra_vni_t *zvni_map_vlan(struct interface *ifp, /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */ /* TODO: Optimize with a hash. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) { + zns = zebra_ns_lookup(NS_DEFAULT); + for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { + tmp_if = (struct interface *)rn->info; + if (!tmp_if) + continue; zif = tmp_if->info; if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) continue; @@ -1750,36 +1730,35 @@ static zebra_vni_t *zvni_map_vlan(struct interface *ifp, if (zif->brslave_info.br_if != br_if) continue; - if (!bridge_vlan_aware) - break; - - if (vxl->access_vlan == vid) + if (!bridge_vlan_aware || vxl->access_vlan == vid) { + found = 1; break; + } } - if (!tmp_if) + if (!found) return NULL; - zvni = zvni_lookup(zvrf, vxl->vni); + zvni = zvni_lookup(vxl->vni); return zvni; } /* * Map SVI and associated bridge to a VNI. This is invoked upon getting * neighbor notifications, to see if they are of interest. - * TODO: Need to make this as a hash table. */ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if) { - struct zebra_vrf *zvrf; - struct listnode *node; - struct interface *tmp_if; + struct zebra_ns *zns; + struct route_node *rn; + struct interface *tmp_if = NULL; struct zebra_if *zif; struct zebra_l2info_bridge *br; - struct zebra_l2info_vxlan *vxl; + struct zebra_l2info_vxlan *vxl = NULL; u_char bridge_vlan_aware; vlanid_t vid = 0; zebra_vni_t *zvni; + int found = 0; if (!br_if) return NULL; @@ -1788,10 +1767,6 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if) if (!IS_ZEBRA_IF_BRIDGE(br_if)) return NULL; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - /* Determine if bridge is VLAN-aware or not */ zif = br_if->info; assert(zif); @@ -1811,7 +1786,11 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if) /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */ /* TODO: Optimize with a hash. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) { + zns = zebra_ns_lookup(NS_DEFAULT); + for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { + tmp_if = (struct interface *)rn->info; + if (!tmp_if) + continue; zif = tmp_if->info; if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) continue; @@ -1822,17 +1801,16 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if) if (zif->brslave_info.br_if != br_if) continue; - if (!bridge_vlan_aware) - break; - - if (vxl->access_vlan == vid) + if (!bridge_vlan_aware || vxl->access_vlan == vid) { + found = 1; break; + } } - if (!tmp_if) + if (!found) return NULL; - zvni = zvni_lookup(zvrf, vxl->vni); + zvni = zvni_lookup(vxl->vni); return zvni; } @@ -1843,15 +1821,16 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if) * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface * itself */ -static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid, - struct interface *br_if) +static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if) { - struct listnode *node; - struct interface *tmp_if; + struct zebra_ns *zns; + struct route_node *rn; + struct interface *tmp_if = NULL; struct zebra_if *zif; struct zebra_l2info_bridge *br; struct zebra_l2info_vlan *vl; u_char bridge_vlan_aware; + int found = 0; /* Defensive check, caller expected to invoke only with valid bridge. */ if (!br_if) @@ -1869,9 +1848,11 @@ static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid, /* Identify corresponding VLAN interface. */ /* TODO: Optimize with a hash. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) { + zns = zebra_ns_lookup(NS_DEFAULT); + for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { + tmp_if = (struct interface *)rn->info; /* Check oper status of the SVI. */ - if (!if_is_operative(tmp_if)) + if (!tmp_if || !if_is_operative(tmp_if)) continue; zif = tmp_if->info; if (!zif || zif->zif_type != ZEBRA_IF_VLAN @@ -1879,11 +1860,13 @@ static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid, continue; vl = (struct zebra_l2info_vlan *)&zif->l2info.vl; - if (vl->vid == vid) + if (vl->vid == vid) { + found = 1; break; + } } - return tmp_if; + return found ? tmp_if : NULL; } /* @@ -1986,9 +1969,10 @@ static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac, /* * Read and populate local MACs and neighbors corresponding to this VNI. */ -static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni, +static void zvni_read_mac_neigh(zebra_vni_t *zvni, struct interface *ifp) { + struct zebra_ns *zns; struct zebra_if *zif; struct interface *vlan_if; struct zebra_l2info_vxlan *vxl; @@ -1996,19 +1980,19 @@ static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni, zif = ifp->info; vxl = &zif->l2info.vxl; + zns = zebra_ns_lookup(NS_DEFAULT); if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u", - ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni, + "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u", + ifp->name, ifp->ifindex, zvni->vni, zif->brslave_info.bridge_ifindex); - macfdb_read_for_bridge(zvrf->zns, ifp, zif->brslave_info.br_if); - vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan, - zif->brslave_info.br_if); + macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if); + vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); if (vlan_if) { - if (advertise_gw_macip_enabled(zvrf, zvni)) { + if (advertise_gw_macip_enabled(zvni)) { /* Add SVI MAC-IP */ zvni_add_macip_for_intf(vlan_if, zvni); @@ -2018,7 +2002,7 @@ static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni, zvni_add_macip_for_intf(vrr_if, zvni); } - neigh_read_for_vlan(zvrf->zns, vlan_if); + neigh_read_for_vlan(zns, vlan_if); } } @@ -2059,11 +2043,14 @@ static void *zvni_alloc(void *p) /* * Look up VNI hash entry. */ -static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni) +static zebra_vni_t *zvni_lookup(vni_t vni) { + struct zebra_vrf *zvrf; zebra_vni_t tmp_vni; zebra_vni_t *zvni = NULL; + zvrf = vrf_info_lookup(VRF_DEFAULT); + assert(zvrf); memset(&tmp_vni, 0, sizeof(zebra_vni_t)); tmp_vni.vni = vni; zvni = hash_lookup(zvrf->vni_table, &tmp_vni); @@ -2074,11 +2061,14 @@ static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni) /* * Add VNI hash entry. */ -static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni) +static zebra_vni_t *zvni_add(vni_t vni) { + struct zebra_vrf *zvrf; zebra_vni_t tmp_zvni; zebra_vni_t *zvni = NULL; + zvrf = vrf_info_lookup(VRF_DEFAULT); + assert(zvrf); memset(&tmp_zvni, 0, sizeof(zebra_vni_t)); tmp_zvni.vni = vni; zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc); @@ -2098,10 +2088,14 @@ static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni) /* * Delete VNI hash entry. */ -static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni) +static int zvni_del(zebra_vni_t *zvni) { + struct zebra_vrf *zvrf; zebra_vni_t *tmp_zvni; + zvrf = vrf_info_lookup(VRF_DEFAULT); + assert(zvrf); + zvni->vxlan_if = NULL; /* Free the neighbor hash table. */ @@ -2123,7 +2117,7 @@ static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni) /* * Inform BGP about local VNI addition. */ -static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni) +static int zvni_send_add_to_client(zebra_vni_t *zvni) { struct zserv *client; struct stream *s; @@ -2136,7 +2130,7 @@ static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni) s = client->obuf; stream_reset(s); - zserv_create_header(s, ZEBRA_VNI_ADD, zvrf_id(zvrf)); + zserv_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT); stream_putl(s, zvni->vni); stream_put_in_addr(s, &zvni->local_vtep_ip); @@ -2144,7 +2138,7 @@ static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni) stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf), + zlog_debug("Send VNI_ADD %u %s to %s", zvni->vni, inet_ntoa(zvni->local_vtep_ip), zebra_route_string(client->proto)); @@ -2155,7 +2149,7 @@ static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni) /* * Inform BGP about local VNI deletion. */ -static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni) +static int zvni_send_del_to_client(vni_t vni) { struct zserv *client; struct stream *s; @@ -2168,14 +2162,14 @@ static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni) s = client->obuf; stream_reset(s); - zserv_create_header(s, ZEBRA_VNI_DEL, zvrf_id(zvrf)); + zserv_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT); stream_putl(s, vni); /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf), vni, + zlog_debug("Send VNI_DEL %u to %s", vni, zebra_route_string(client->proto)); client->vnidel_cnt++; @@ -2186,18 +2180,23 @@ static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni) * Build the VNI hash table by going over the VxLAN interfaces. This * is called when EVPN (advertise-all-vni) is enabled. */ -static void zvni_build_hash_table(struct zebra_vrf *zvrf) +static void zvni_build_hash_table() { - struct listnode *node; + struct zebra_ns *zns; + struct route_node *rn; struct interface *ifp; /* Walk VxLAN interfaces and create VNI hash. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, ifp)) { + zns = zebra_ns_lookup(NS_DEFAULT); + for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { struct zebra_if *zif; struct zebra_l2info_vxlan *vxl; zebra_vni_t *zvni; vni_t vni; + ifp = (struct interface *)rn->info; + if (!ifp) + continue; zif = ifp->info; if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) continue; @@ -2207,24 +2206,24 @@ static void zvni_build_hash_table(struct zebra_vrf *zvrf) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s", - zvrf_id(zvrf), ifp->name, ifp->ifindex, vni, + "Create VNI hash for intf %s(%u) VNI %u local IP %s", + ifp->name, ifp->ifindex, vni, inet_ntoa(vxl->vtep_ip)); /* VNI hash entry is not expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (zvni) { zlog_err( - "VNI hash already present for VRF %d IF %s(%u) VNI %u", - zvrf_id(zvrf), ifp->name, ifp->ifindex, vni); + "VNI hash already present for IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); continue; } - zvni = zvni_add(zvrf, vni); + zvni = zvni_add(vni); if (!zvni) { zlog_err( - "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u", - zvrf_id(zvrf), ifp->name, ifp->ifindex, vni); + "Failed to add VNI hash, IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); return; } @@ -2233,7 +2232,7 @@ static void zvni_build_hash_table(struct zebra_vrf *zvrf) /* Inform BGP if interface is up and mapped to bridge. */ if (if_is_operative(ifp) && zif->brslave_info.br_if) - zvni_send_add_to_client(zvrf, zvni); + zvni_send_add_to_client(zvni); } } @@ -2359,14 +2358,14 @@ static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf) return; /* Free up all neighbors and MACs, if any. */ - zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH); - zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC); + zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH); + zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC); /* Free up all remote VTEPs, if any. */ zvni_vtep_del_all(zvni, 1); /* Delete the hash entry. */ - zvni_del(zvrf, zvni); + zvni_del(zvni); } @@ -2383,9 +2382,9 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, struct neigh_walk_ctx wctx; json_object *json = NULL; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (use_json) vty_out(vty, "{}\n"); @@ -2437,7 +2436,7 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf, json_object *json = NULL; void *args[2]; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; if (use_json) @@ -2467,9 +2466,9 @@ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty, zebra_neigh_t *n; json_object *json = NULL; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (use_json) vty_out(vty, "{}\n"); @@ -2510,9 +2509,9 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, struct neigh_walk_ctx wctx; json_object *json = NULL; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (use_json) vty_out(vty, "{}\n"); @@ -2551,9 +2550,9 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, json_object *json = NULL; json_object *json_mac = NULL; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (use_json) vty_out(vty, "{}\n"); @@ -2561,7 +2560,7 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "%% VNI %u does not exist\n", vni); return; } - num_macs = hashcount(zvni->mac_table); + num_macs = num_valid_macs(zvni); if (!num_macs) return; @@ -2603,7 +2602,7 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf, struct mac_walk_ctx wctx; json_object *json = NULL; - if (!EVPN_ENABLED(zvrf)) { + if (!is_evpn_enabled()) { if (use_json) vty_out(vty, "{}\n"); return; @@ -2634,7 +2633,7 @@ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty, struct mac_walk_ctx wctx; json_object *json = NULL; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; if (use_json) @@ -2663,9 +2662,9 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf, zebra_vni_t *zvni; zebra_mac_t *mac; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { vty_out(vty, "%% VNI %u does not exist\n", vni); return; @@ -2693,9 +2692,9 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, json_object *json = NULL; json_object *json_mac = NULL; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (use_json) vty_out(vty, "{}\n"); @@ -2703,7 +2702,7 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "%% VNI %u does not exist\n", vni); return; } - num_macs = hashcount(zvni->mac_table); + num_macs = num_valid_macs(zvni); if (!num_macs) return; @@ -2741,9 +2740,9 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, json_object *json = NULL; void *args[2]; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (use_json) vty_out(vty, "{}\n"); @@ -2773,7 +2772,7 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf, json_object *json = NULL; void *args[2]; - if (!EVPN_ENABLED(zvrf)) + if (!is_evpn_enabled()) return; num_vnis = hashcount(zvrf->vni_table); if (!num_vnis) { @@ -2819,7 +2818,6 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp, { zebra_vni_t *zvni; zebra_neigh_t *n; - struct zebra_vrf *zvrf; char buf[INET6_ADDRSTRLEN]; char buf2[ETHER_ADDR_STRLEN]; zebra_mac_t *zmac; @@ -2838,8 +2836,8 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp, } if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)), + zlog_debug("Del neighbor %s intf %s(%u) -> VNI %u", + ipaddr2str(ip, buf, sizeof(buf)), ifp->name, ifp->ifindex, zvni->vni); /* If entry doesn't exist, nothing to do. */ @@ -2851,8 +2849,8 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp, if (!zmac) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_err( - "%u: trying to del a neigh %s without a mac %s on VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)), + "Trying to del a neigh %s without a mac %s on VNI %u", + ipaddr2str(ip, buf, sizeof(buf)), prefix_mac2str(&n->emac, buf2, sizeof(buf2)), zvni->vni); @@ -2867,13 +2865,9 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp, return 0; } - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - assert(zvrf); - /* Remove neighbor from BGP. */ if (IS_ZEBRA_NEIGH_ACTIVE(n)) - zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac, + zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); /* Delete this neighbor entry. */ @@ -2899,7 +2893,6 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, { zebra_vni_t *zvni; zebra_neigh_t *n; - struct zebra_vrf *zvrf; zebra_mac_t *zmac, *old_zmac; char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; @@ -2911,15 +2904,11 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, if (!zvni) return 0; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - assert(zvrf); - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x " + "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x " "%s-> VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), + ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, state, ext_learned ? "ext-learned " : "", zvni->vni); @@ -2929,15 +2918,13 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, if (!zmac) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u: AUTO MAC %s created for neigh %s on VNI %u", - ifp->vrf_id, + "AUTO MAC %s created for neigh %s on VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni); zmac = zvni_mac_add(zvni, macaddr); if (!zmac) { - zlog_warn("%u:Failed to add MAC %s VNI %u", - zvrf_id(zvrf), + zlog_warn("Failed to add MAC %s VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), zvni->vni); return -1; @@ -2969,7 +2956,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, * as this means a different MACIP route. * Also, need to do some unlinking/relinking. */ - zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, + zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); old_zmac = zvni_mac_lookup(zvni, &n->emac); if (old_zmac) { @@ -3002,8 +2989,8 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, n = zvni_neigh_add(zvni, ip, macaddr); if (!n) { zlog_err( - "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), + "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", + ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, zvni->vni); return -1; @@ -3018,8 +3005,8 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u: Skipping neigh %s add to client as MAC %s is not local on VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), + "Skipping neigh %s add to client as MAC %s is not local on VNI %u", + ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), zvni->vni); @@ -3028,13 +3015,13 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, /* Inform BGP. */ if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u: neigh %s (MAC %s) is now ACTIVE on VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), + zlog_debug("neigh %s (MAC %s) is now ACTIVE on VNI %u", + ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), zvni->vni); ZEBRA_NEIGH_SET_ACTIVE(n); - return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, macaddr, 0); + return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0); } @@ -3082,21 +3069,20 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s", - zvrf_id(zvrf), + "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s", prefix_mac2str(&macaddr, buf, sizeof(buf)), ipaddr2str(&ip, buf1, sizeof(buf1)), vni, inet_ntoa(vtep_ip), zebra_route_string(client->proto)); /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "Failed to locate VNI hash upon remote MACIP DEL, " - "VRF %d VNI %u", - zvrf_id(zvrf), vni); + "VNI %u", + vni); continue; } ifp = zvni->vxlan_if; @@ -3129,10 +3115,9 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length, if (n && !mac) { zlog_err( - "failed to locate MAC %s for neigh %s in VRF %u VNI %u", + "Failed to locate MAC %s for neigh %s VNI %u", prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), - zvrf_id(zvrf), vni); + ipaddr2str(&ip, buf1, sizeof(buf1)), vni); continue; } @@ -3163,7 +3148,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length, } } else { if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - zvni_process_neigh_on_remote_mac_del(zvrf, zvni, + zvni_process_neigh_on_remote_mac_del(zvni, mac); if (list_isempty(mac->neigh_list)) { @@ -3234,19 +3219,19 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s", - zvrf_id(zvrf), sticky ? "sticky " : "", + "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s", + sticky ? "sticky " : "", prefix_mac2str(&macaddr, buf, sizeof(buf)), ipaddr2str(&ip, buf1, sizeof(buf1)), vni, inet_ntoa(vtep_ip), zebra_route_string(client->proto)); /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { zlog_err( - "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u", - zvrf_id(zvrf), vni); + "Failed to locate VNI hash upon remote MACIP ADD, VNI %u", + vni); continue; } ifp = zvni->vxlan_if; @@ -3272,8 +3257,8 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, if (!zvtep) { if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { zlog_err( - "Failed to add remote VTEP, VRF %d VNI %u zvni %p", - zvrf_id(zvrf), vni, zvni); + "Failed to add remote VTEP, VNI %u zvni %p", + vni, zvni); continue; } @@ -3298,8 +3283,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, mac = zvni_mac_add(zvni, &macaddr); if (!mac) { zlog_warn( - "%u:Failed to add MAC %s VNI %u Remote VTEP %s", - zvrf_id(zvrf), + "Failed to add MAC %s VNI %u Remote VTEP %s", prefix_mac2str(&macaddr, buf, sizeof(buf)), vni, inet_ntoa(vtep_ip)); @@ -3322,7 +3306,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, else UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - zvni_process_neigh_on_remote_mac_add(zvrf, zvni, mac); + zvni_process_neigh_on_remote_mac_add(zvni, mac); /* Install the entry. */ zvni_mac_install(zvni, mac); @@ -3350,8 +3334,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, n = zvni_neigh_add(zvni, &ip, &macaddr); if (!n) { zlog_warn( - "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", - zvrf_id(zvrf), + "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", ipaddr2str(&ip, buf1, sizeof(buf1)), prefix_mac2str(&macaddr, buf, @@ -3397,7 +3380,6 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp, struct ethaddr *macaddr, vlanid_t vid) { struct zebra_if *zif; - struct zebra_vrf *zvrf; struct zebra_l2info_vxlan *vxl; vni_t vni; zebra_vni_t *zvni; @@ -3410,16 +3392,12 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp, vxl = &zif->l2info.vxl; vni = vxl->vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing to do. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; /* Locate hash entry; it is expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) return 0; @@ -3434,13 +3412,13 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local", - ifp->vrf_id, prefix_mac2str(macaddr, buf, sizeof(buf)), + "Add/update remote MAC %s intf %s(%u) VNI %u - del local", + prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vni); /* Remove MAC from BGP. */ sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0; - zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr, + zvni_mac_send_del_to_client(zvni->vni, macaddr, (sticky ? ZEBRA_MAC_TYPE_STICKY : 0)); /* @@ -3467,7 +3445,6 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp, struct ethaddr *macaddr, vlanid_t vid) { struct zebra_if *zif; - struct zebra_vrf *zvrf; struct zebra_l2info_vxlan *vxl; vni_t vni; zebra_vni_t *zvni; @@ -3479,16 +3456,12 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp, vxl = &zif->l2info.vxl; vni = vxl->vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing to do. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; /* Locate hash entry; it is expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) return 0; @@ -3502,8 +3475,7 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp, return 0; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd", - ifp->vrf_id, + zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vni); @@ -3519,7 +3491,6 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, { zebra_vni_t *zvni; zebra_mac_t *mac; - struct zebra_vrf *zvrf; char buf[ETHER_ADDR_STRLEN]; u_char sticky; @@ -3536,8 +3507,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, } if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u", - ifp->vrf_id, + zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid, zvni->vni); @@ -3550,17 +3520,13 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return 0; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - assert(zvrf); - /* Remove MAC from BGP. */ sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0; - zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr, + zvni_mac_send_del_to_client(zvni->vni, macaddr, (sticky ? ZEBRA_MAC_TYPE_STICKY : 0)); /* Update all the neigh entries associated with this mac */ - zvni_process_neigh_on_local_mac_del(zvrf, zvni, mac); + zvni_process_neigh_on_local_mac_del(zvni, mac); /* * If there are no neigh associated with the mac delete the mac @@ -3586,7 +3552,6 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, { zebra_vni_t *zvni; zebra_mac_t *mac; - struct zebra_vrf *zvrf; char buf[ETHER_ADDR_STRLEN]; int add = 1; u_char mac_sticky; @@ -3598,8 +3563,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, if (!zvni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI", - ifp->vrf_id, sticky ? "sticky " : "", + "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI", + sticky ? "sticky " : "", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid); return 0; @@ -3613,8 +3578,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u", - ifp->vrf_id, sticky ? "sticky " : "", + "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u", + sticky ? "sticky " : "", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid, zvni->vni); @@ -3638,9 +3603,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, && mac->fwd_info.local.vid == vid) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, " + "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, " "entry exists and has not changed ", - ifp->vrf_id, sticky ? "sticky " : "", prefix_mac2str(macaddr, buf, sizeof(buf)), @@ -3671,15 +3635,10 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, } } - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); - assert(zvrf); - if (!mac) { mac = zvni_mac_add(zvni, macaddr); if (!mac) { - zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u", - ifp->vrf_id, + zlog_err("Failed to add MAC %s intf %s(%u) VID %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid); return -1; @@ -3701,8 +3660,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, /* Inform BGP if required. */ if (add) { - zvni_process_neigh_on_local_mac_add(zvrf, zvni, mac); - return zvni_mac_send_add_to_client(zvrf, zvni->vni, macaddr, + zvni_process_neigh_on_local_mac_add(zvni, mac); + return zvni_mac_send_add_to_client(zvni->vni, macaddr, sticky); } @@ -3724,6 +3683,13 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, struct interface *ifp; struct zebra_if *zif; + assert(is_evpn_enabled()); + if (zvrf_id(zvrf) != VRF_DEFAULT) { + zlog_err("Recv MACIP DEL for non-default VRF %u", + zvrf_id(zvrf)); + return -1; + } + s = client->ibuf; while (l < length) { @@ -3734,18 +3700,18 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, l += IPV4_MAX_BYTELEN; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s", - zvrf_id(zvrf), inet_ntoa(vtep_ip), vni, + zlog_debug("Recv VTEP_DEL %s VNI %u from %s", + inet_ntoa(vtep_ip), vni, zebra_route_string(client->proto)); /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "Failed to locate VNI hash upon remote VTEP DEL, " - "VRF %d VNI %u", - zvrf_id(zvrf), vni); + "VNI %u", + vni); continue; } @@ -3795,7 +3761,12 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, struct interface *ifp; struct zebra_if *zif; - assert(EVPN_ENABLED(zvrf)); + assert(is_evpn_enabled()); + if (zvrf_id(zvrf) != VRF_DEFAULT) { + zlog_err("Recv MACIP ADD for non-default VRF %u", + zvrf_id(zvrf)); + return -1; + } s = client->ibuf; @@ -3807,16 +3778,16 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, l += IPV4_MAX_BYTELEN; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s", - zvrf_id(zvrf), inet_ntoa(vtep_ip), vni, + zlog_debug("Recv VTEP_ADD %s VNI %u from %s", + inet_ntoa(vtep_ip), vni, zebra_route_string(client->proto)); /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { zlog_err( - "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u", - zvrf_id(zvrf), vni); + "Failed to locate VNI hash upon remote VTEP ADD, VNI %u", + vni); continue; } @@ -3841,8 +3812,8 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { zlog_err( - "Failed to add remote VTEP, VRF %d VNI %u zvni %p", - zvrf_id(zvrf), vni, zvni); + "Failed to add remote VTEP, VNI %u zvni %p", + vni, zvni); continue; } @@ -3866,16 +3837,12 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, struct ipaddr ip; struct ethaddr macaddr; zebra_vni_t *zvni = NULL; - struct zebra_vrf *zvrf = NULL; memset(&ip, 0, sizeof(struct ipaddr)); memset(&macaddr, 0, sizeof(struct ethaddr)); - zvrf = vrf_info_lookup(ifp->vrf_id); - if (!zvrf) - return -1; - - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; if (IS_ZEBRA_IF_MACVLAN(ifp)) { @@ -3896,8 +3863,8 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifp_zif->link_ifindex); if (!svi_if) { - zlog_err("%u:MACVLAN %s(%u) without link information", - ifp->vrf_id, ifp->name, ifp->ifindex); + zlog_err("MACVLAN %s(%u) without link information", + ifp->name, ifp->ifindex); return -1; } @@ -3948,7 +3915,7 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, /* check if we are advertising gw macip routes */ - if (!advertise_gw_macip_enabled(zvrf, zvni)) + if (!advertise_gw_macip_enabled(zvni)) return 0; memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); @@ -4002,8 +3969,8 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) } if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors", - ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni); + zlog_debug("SVI %s(%u) VNI %u is UP, installing neighbors", + ifp->name, ifp->ifindex, zvni->vni); /* Install any remote neighbors for this VNI. */ memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx)); @@ -4020,17 +3987,12 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) int zebra_vxlan_if_down(struct interface *ifp) { struct zebra_if *zif; - struct zebra_vrf *zvrf; zebra_vni_t *zvni; struct zebra_l2info_vxlan *vxl; vni_t vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing further to be done. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; zif = ifp->info; @@ -4039,26 +4001,26 @@ int zebra_vxlan_if_down(struct interface *ifp) vni = vxl->vni; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp->vrf_id, + zlog_debug("Intf %s(%u) VNI %u is DOWN", ifp->name, ifp->ifindex, vni); /* Locate hash entry; it is expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { zlog_err( - "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u", - ifp->vrf_id, ifp->name, ifp->ifindex, vni); + "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); return -1; } assert(zvni->vxlan_if == ifp); /* Delete this VNI from BGP. */ - zvni_send_del_to_client(zvrf, zvni->vni); + zvni_send_del_to_client(zvni->vni); /* Free up all neighbors and MACs, if any. */ - zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH); - zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC); + zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH); + zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC); /* Free up all remote VTEPs, if any. */ zvni_vtep_del_all(zvni, 1); @@ -4072,17 +4034,12 @@ int zebra_vxlan_if_down(struct interface *ifp) int zebra_vxlan_if_up(struct interface *ifp) { struct zebra_if *zif; - struct zebra_vrf *zvrf; zebra_vni_t *zvni; struct zebra_l2info_vxlan *vxl; vni_t vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing further to be done. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; zif = ifp->info; @@ -4091,15 +4048,15 @@ int zebra_vxlan_if_up(struct interface *ifp) vni = vxl->vni; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp->vrf_id, + zlog_debug("Intf %s(%u) VNI %u is UP", ifp->name, ifp->ifindex, vni); /* Locate hash entry; it is expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { zlog_err( - "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u", - ifp->vrf_id, ifp->name, ifp->ifindex, vni); + "Failed to locate VNI hash at UP, IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); return -1; } @@ -4108,8 +4065,8 @@ int zebra_vxlan_if_up(struct interface *ifp) /* If part of a bridge, inform BGP about this VNI. */ /* Also, read and populate local MACs and neighbors. */ if (zif->brslave_info.br_if) { - zvni_send_add_to_client(zvrf, zvni); - zvni_read_mac_neigh(zvrf, zvni, ifp); + zvni_send_add_to_client(zvni); + zvni_read_mac_neigh(zvni, ifp); } return 0; @@ -4122,17 +4079,12 @@ int zebra_vxlan_if_up(struct interface *ifp) int zebra_vxlan_if_del(struct interface *ifp) { struct zebra_if *zif; - struct zebra_vrf *zvrf; zebra_vni_t *zvni; struct zebra_l2info_vxlan *vxl; vni_t vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing further to be done. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; zif = ifp->info; @@ -4141,32 +4093,32 @@ int zebra_vxlan_if_del(struct interface *ifp) vni = vxl->vni; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:Del VNI %u intf %s(%u)", ifp->vrf_id, vni, - ifp->name, ifp->ifindex); + zlog_debug("Del VNI %u intf %s(%u)", + vni, ifp->name, ifp->ifindex); /* Locate hash entry; it is expected to exist. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { zlog_err( - "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u", - ifp->vrf_id, ifp->name, ifp->ifindex, vni); + "Failed to locate VNI hash at del, IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); return 0; } /* Delete VNI from BGP. */ - zvni_send_del_to_client(zvrf, zvni->vni); + zvni_send_del_to_client(zvni->vni); /* Free up all neighbors and MAC, if any. */ - zvni_neigh_del_all(zvrf, zvni, 0, 0, DEL_ALL_NEIGH); - zvni_mac_del_all(zvrf, zvni, 0, 0, DEL_ALL_MAC); + zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH); + zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC); /* Free up all remote VTEPs, if any. */ zvni_vtep_del_all(zvni, 0); /* Delete the hash entry. */ - if (zvni_del(zvrf, zvni)) { - zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u", - zvni, ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni); + if (zvni_del(zvni)) { + zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u", + zvni, ifp->name, ifp->ifindex, zvni->vni); return -1; } @@ -4179,17 +4131,12 @@ int zebra_vxlan_if_del(struct interface *ifp) int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) { struct zebra_if *zif; - struct zebra_vrf *zvrf; zebra_vni_t *zvni; struct zebra_l2info_vxlan *vxl; vni_t vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing further to be done. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; zif = ifp->info; @@ -4198,19 +4145,19 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) vni = vxl->vni; /* Update VNI hash. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { zlog_err( - "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u", - ifp->vrf_id, ifp->name, ifp->ifindex, vni); + "Failed to find VNI hash on update, IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); return -1; } if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s " + "Update VNI %u intf %s(%u) VLAN %u local IP %s " "master %u chg 0x%x", - ifp->vrf_id, vni, ifp->name, ifp->ifindex, + vni, ifp->name, ifp->ifindex, vxl->access_vlan, inet_ntoa(vxl->vtep_ip), zif->brslave_info.bridge_ifindex, chgflags); @@ -4219,9 +4166,9 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { /* Delete from client, remove all remote VTEPs */ /* Also, free up all MACs and neighbors. */ - zvni_send_del_to_client(zvrf, zvni->vni); - zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH); - zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC); + zvni_send_del_to_client(zvni->vni); + zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH); + zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC); zvni_vtep_del_all(zvni, 1); return 0; } @@ -4231,8 +4178,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) /* Remove all existing local neighbors and MACs for this VNI * (including from BGP) */ - zvni_neigh_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC); - zvni_mac_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC); + zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC); + zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC); } zvni->local_vtep_ip = vxl->vtep_ip; @@ -4248,19 +4195,19 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) /* Inform BGP, if there is a change of interest. */ if (chgflags & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE)) - zvni_send_add_to_client(zvrf, zvni); + zvni_send_add_to_client(zvni); /* If there is a valid new master or a VLAN mapping change, read and * populate local MACs and neighbors. Also, reinstall any remote MACs * and neighbors for this VNI (based on new VLAN). */ if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) - zvni_read_mac_neigh(zvrf, zvni, ifp); + zvni_read_mac_neigh(zvni, ifp); else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { struct mac_walk_ctx m_wctx; struct neigh_walk_ctx n_wctx; - zvni_read_mac_neigh(zvrf, zvni, ifp); + zvni_read_mac_neigh(zvni, ifp); memset(&m_wctx, 0, sizeof(struct mac_walk_ctx)); m_wctx.zvni = zvni; @@ -4281,17 +4228,12 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) int zebra_vxlan_if_add(struct interface *ifp) { struct zebra_if *zif; - struct zebra_vrf *zvrf; zebra_vni_t *zvni; struct zebra_l2info_vxlan *vxl; vni_t vni; - /* Locate VRF corresponding to interface. */ - zvrf = vrf_info_lookup(ifp->vrf_id); - assert(zvrf); - - /* If EVPN is not enabled, nothing further to be done. */ - if (!EVPN_ENABLED(zvrf)) + /* Check if EVPN is enabled. */ + if (!is_evpn_enabled()) return 0; zif = ifp->info; @@ -4301,19 +4243,19 @@ int zebra_vxlan_if_add(struct interface *ifp) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u", - ifp->vrf_id, vni, ifp->name, ifp->ifindex, + "Add VNI %u intf %s(%u) VLAN %u local IP %s master %u", + vni, ifp->name, ifp->ifindex, vxl->access_vlan, inet_ntoa(vxl->vtep_ip), zif->brslave_info.bridge_ifindex); /* Create or update VNI hash. */ - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) { - zvni = zvni_add(zvrf, vni); + zvni = zvni_add(vni); if (!zvni) { zlog_err( - "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u", - ifp->vrf_id, ifp->name, ifp->ifindex, vni); + "Failed to add VNI hash, IF %s(%u) VNI %u", + ifp->name, ifp->ifindex, vni); return -1; } } @@ -4326,10 +4268,10 @@ int zebra_vxlan_if_add(struct interface *ifp) return 0; /* Inform BGP */ - zvni_send_add_to_client(zvrf, zvni); + zvni_send_add_to_client(zvni); /* Read and populate local MACs and neighbors */ - zvni_read_mac_neigh(zvrf, zvni, ifp); + zvni_read_mac_neigh(zvni, ifp); return 0; } @@ -4347,16 +4289,21 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock, zebra_vni_t *zvni = NULL; struct interface *ifp = NULL; + if (zvrf_id(zvrf) != VRF_DEFAULT) { + zlog_err("EVPN GW-MACIP Adv for non-default VRF %u", + zvrf_id(zvrf)); + return -1; + } + s = client->ibuf; advertise = stream_getc(s); vni = stream_get3(s); if (!vni) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:EVPN gateway macip Adv %s, currently %s", - zvrf_id(zvrf), + zlog_debug("EVPN gateway macip Adv %s, currently %s", advertise ? "enabled" : "disabled", - advertise_gw_macip_enabled(zvrf, NULL) + advertise_gw_macip_enabled(NULL) ? "enabled" : "disabled"); @@ -4365,12 +4312,12 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock, zvrf->advertise_gw_macip = advertise; - if (advertise_gw_macip_enabled(zvrf, zvni)) + if (advertise_gw_macip_enabled(zvni)) hash_iterate(zvrf->vni_table, - zvni_gw_macip_add_for_vni_hash, zvrf); + zvni_gw_macip_add_for_vni_hash, NULL); else hash_iterate(zvrf->vni_table, - zvni_gw_macip_del_for_vni_hash, zvrf); + zvni_gw_macip_del_for_vni_hash, NULL); } else { struct zebra_if *zif = NULL; @@ -4380,14 +4327,13 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "%u:EVPN gateway macip Adv %s on VNI %d , currently %s", - zvrf_id(zvrf), + "EVPN gateway macip Adv %s on VNI %d , currently %s", advertise ? "enabled" : "disabled", vni, - advertise_gw_macip_enabled(zvrf, zvni) + advertise_gw_macip_enabled(zvni) ? "enabled" : "disabled"); - zvni = zvni_lookup(zvrf, vni); + zvni = zvni_lookup(vni); if (!zvni) return 0; @@ -4408,12 +4354,12 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock, zl2_info = zif->l2info.vxl; - vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan, + vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if); if (!vlan_if) return 0; - if (advertise_gw_macip_enabled(zvrf, zvni)) { + if (advertise_gw_macip_enabled(zvni)) { /* Add primary SVI MAC-IP */ zvni_add_macip_for_intf(vlan_if, zvni); @@ -4448,25 +4394,31 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, struct stream *s; int advertise; + if (zvrf_id(zvrf) != VRF_DEFAULT) { + zlog_err("EVPN VNI Adv for non-default VRF %u", + zvrf_id(zvrf)); + return -1; + } + s = client->ibuf; advertise = stream_getc(s); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf), + zlog_debug("EVPN VNI Adv %s, currently %s", advertise ? "enabled" : "disabled", - EVPN_ENABLED(zvrf) ? "enabled" : "disabled"); + is_evpn_enabled() ? "enabled" : "disabled"); if (zvrf->advertise_all_vni == advertise) return 0; zvrf->advertise_all_vni = advertise; - if (EVPN_ENABLED(zvrf)) { + if (is_evpn_enabled()) { /* Build VNI hash table and inform BGP. */ - zvni_build_hash_table(zvrf); + zvni_build_hash_table(); /* Add all SVI (L3 GW) MACs to BGP*/ hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash, - zvrf); + NULL); /* Read the MAC FDB */ macfdb_read(zvrf->zns); @@ -4498,6 +4450,8 @@ void zebra_vxlan_init_tables(struct zebra_vrf *zvrf) /* Close all VNI handling */ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) { + if (!zvrf) + return; hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf); hash_free(zvrf->vni_table); } diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index f7c1afc959..8b43615bb3 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -35,6 +35,14 @@ /* Is EVPN enabled? */ #define EVPN_ENABLED(zvrf) (zvrf)->advertise_all_vni +static inline int +is_evpn_enabled() +{ + struct zebra_vrf *zvrf = NULL; + zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + return zvrf ? zvrf->advertise_all_vni : 0; +} + /* VxLAN interface change flags of interest. */ #define ZEBRA_VXLIF_LOCAL_IP_CHANGE 0x1 diff --git a/zebra/zserv.c b/zebra/zserv.c index fd2c5dd97c..cbc9f2bed9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -825,6 +825,7 @@ static int zserv_fec_register(struct zserv *client, int sock, u_short length) while (l < length) { flags = stream_getw(s); + memset(&p, 0, sizeof(p)); p.family = stream_getw(s); if (p.family != AF_INET && p.family != AF_INET6) { zlog_err( @@ -875,6 +876,7 @@ static int zserv_fec_unregister(struct zserv *client, int sock, u_short length) while (l < length) { // flags = stream_getw(s); (void)stream_getw(s); + memset(&p, 0, sizeof(p)); p.family = stream_getw(s); if (p.family != AF_INET && p.family != AF_INET6) { zlog_err( @@ -998,14 +1000,13 @@ static int zread_interface_add(struct zserv *client, u_short length, struct zebra_vrf *zvrf) { struct vrf *vrf; - struct listnode *ifnode, *ifnnode; struct interface *ifp; /* Interface information is needed. */ vrf_bitmap_set(client->ifinfo, zvrf_id(zvrf)); RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - for (ALL_LIST_ELEMENTS(vrf->iflist, ifnode, ifnnode, ifp)) { + FOR_ALL_INTERFACES (vrf, ifp) { /* Skip pseudo interface. */ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) continue; |
