diff options
187 files changed, 4800 insertions, 3430 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 6a8f9bb75f..239ab71f06 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -279,8 +279,7 @@ babel_load_state_file(void) if(fd >= 0 && rc < 0) { zlog_err("unlink(babel-state): %s", safe_strerror(errno)); /* If we couldn't unlink it, it's probably stale. */ - close(fd); - fd = -1; + goto fini; } if(fd >= 0) { char buf[100]; @@ -315,9 +314,12 @@ babel_load_state_file(void) zlog_err("Couldn't parse babel-state."); } } - close(fd); - fd = -1; + goto fini; } +fini: + if (fd >= 0) + close(fd); + return ; } static void diff --git a/babeld/neighbour.c b/babeld/neighbour.c index 5bf7e06fae..48a32c4a9c 100644 --- a/babeld/neighbour.c +++ b/babeld/neighbour.c @@ -165,7 +165,6 @@ update_neighbour(struct neighbour *neigh, int hello, int hello_interval) if(missed_hellos > 0) { neigh->reach >>= missed_hellos; neigh->hello_seqno = seqno_plus(neigh->hello_seqno, missed_hellos); - missed_hellos = 0; rc = 1; } 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 b9f23a387e..0c2a2f6fe9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -391,7 +391,7 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new, int exist_cluster; int internal_as_route; int confed_as_route; - int ret; + int ret = 0; char new_buf[PATH_ADDPATH_STR_BUFFER]; char exist_buf[PATH_ADDPATH_STR_BUFFER]; u_int32_t new_mm_seq; @@ -488,8 +488,6 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new, } /* 1. Weight check. */ - new_weight = exist_weight = 0; - new_weight = newattr->weight; exist_weight = existattr->weight; @@ -6502,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 */ - 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]); - } else { + /* Print aspath */ + if (attr->aspath) { if (json_paths) - json_object_string_add(json_path, "alert", - "No attributes"); + json_object_string_add(json_path, "aspath", + attr->aspath->str); 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(); @@ -8124,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\": { ", @@ -8148,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) { @@ -8411,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, @@ -9092,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, @@ -11415,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..355d1037b8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9868,17 +9868,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..f979457244 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,10 +236,6 @@ 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; @@ -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); @@ -1290,10 +1292,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..308698e1c5 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); @@ -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..5ae27a2878 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -2327,8 +2327,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 +2404,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); } } @@ -3420,7 +3419,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 +3824,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..6e31b63451 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -490,7 +490,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_import.c b/bgpd/rfapi/rfapi_import.c index d963a759ac..083a549307 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -3861,6 +3861,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 +3888,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..7bfc8882e2 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); } 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/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/debian/frr.logrotate b/debian/frr.logrotate index 9a1fa2149b..2b4acd89c7 100644 --- a/debian/frr.logrotate +++ b/debian/frr.logrotate @@ -22,6 +22,6 @@ pids="$pids $(cat /var/run/frr/$i.pid)" fi done - [ -n "$pids" ] && kill -USR1 $pids + [ -n "$pids" ] && kill -USR1 $pids || true endscript } 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/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..b74127aa42 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]) { 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..50e6b7b3be 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -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..59ec571684 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*/ @@ -138,24 +134,29 @@ static int eigrp_write_interface(struct vty *vty) { struct listnode *node; struct interface *ifp; + struct eigrp_interface *ei; for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + ei = ifp->info; + if (!ei) + continue; + 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..66f03b776e 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,10 @@ 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; return 0; } @@ -225,8 +223,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 +237,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 +253,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 +300,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 +310,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 +320,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; } diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index ee60898f86..c70e198bdb 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -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..4179de1c01 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 */ @@ -1339,3 +1345,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 34fcf8f8c6..3008fb6a1e 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -153,7 +153,7 @@ static int isis_vertex_queue_tent_cmp(void *a, void *b) if (va->insert_counter > vb->insert_counter) return 1; - assert(!"Vertizes should be strictly ordered"); + return 0; } static struct skiplist *isis_vertex_queue_skiplist(void) @@ -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..5a4fe82c91 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); 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/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/adjacency.c b/ldpd/adjacency.c index 5b0723a008..7e4f0fd78b 100644 --- a/ldpd/adjacency.c +++ b/ldpd/adjacency.c @@ -60,11 +60,11 @@ adj_compare(const struct adj *a, const struct adj *b) switch (a->source.type) { case HELLO_LINK: - if (strcmp(a->source.link.ia->iface->name, - b->source.link.ia->iface->name) < 0) + if (if_cmp_name_func((char *)a->source.link.ia->iface->name, + (char *)b->source.link.ia->iface->name) < 0) return (-1); - if (strcmp(a->source.link.ia->iface->name, - b->source.link.ia->iface->name) > 0) + if (if_cmp_name_func((char *)a->source.link.ia->iface->name, + (char *)b->source.link.ia->iface->name) > 0) return (1); return (ldp_addrcmp(a->source.link.ia->af, &a->source.link.src_addr, &b->source.link.src_addr)); diff --git a/ldpd/interface.c b/ldpd/interface.c index ac48520f7b..bbcea9f553 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -45,7 +45,7 @@ RB_GENERATE(iface_head, iface, entry, iface_compare) static __inline int iface_compare(const struct iface *a, const struct iface *b) { - return (strcmp(a->name, b->name)); + return (if_cmp_name_func((char *)a->name, (char *)b->name)); } struct iface * @@ -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/l2vpn.c b/ldpd/l2vpn.c index 9bad503b9c..f9f577d564 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -114,7 +114,7 @@ l2vpn_exit(struct l2vpn *l2vpn) static __inline int l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b) { - return (strcmp(a->ifname, b->ifname)); + return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname)); } struct l2vpn_if * @@ -177,7 +177,7 @@ l2vpn_if_update(struct l2vpn_if *lif) static __inline int l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b) { - return (strcmp(a->ifname, b->ifname)); + return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname)); } struct l2vpn_pw * 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_vty.h b/ldpd/ldp_vty.h index 3d2072f1e5..5e9df4aafe 100644 --- a/ldpd/ldp_vty.h +++ b/ldpd/ldp_vty.h @@ -38,8 +38,8 @@ int ldp_l2vpn_config_write(struct vty *); int ldp_debug_config_write(struct vty *); int ldp_vty_mpls_ldp (struct vty *, const char *); int ldp_vty_address_family (struct vty *, const char *, const char *); -int ldp_vty_disc_holdtime(struct vty *, const char *, const char *, long); -int ldp_vty_disc_interval(struct vty *, const char *, const char *, long); +int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long); +int ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long); int ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *); int ldp_vty_nbr_session_holdtime(struct vty *, const char *, struct in_addr, long); int ldp_vty_af_session_holdtime(struct vty *, const char *, long); @@ -69,13 +69,16 @@ int ldp_vty_l2vpn_pw_pwid(struct vty *, const char *, long); int ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *); int ldp_vty_clear_nbr(struct vty *, const char *); int ldp_vty_debug(struct vty *, const char *, const char *, const char *, const char *); -int ldp_vty_show_binding(struct vty *, const char *, const char *, const char *); +int ldp_vty_show_binding(struct vty *, const char *, const char *, int, + const char *, unsigned long, unsigned long, const char *, const char *); int ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *); int ldp_vty_show_interface(struct vty *, const char *, const char *); int ldp_vty_show_capabilities(struct vty *, const char *); -int ldp_vty_show_neighbor(struct vty *, int, const char *, const char *); -int ldp_vty_show_atom_binding(struct vty *, const char *); -int ldp_vty_show_atom_vc(struct vty *, const char *); +int ldp_vty_show_neighbor(struct vty *, const char *, int, const char *, const char *); +int ldp_vty_show_atom_binding(struct vty *, const char *, unsigned long, + unsigned long, const char *); +int ldp_vty_show_atom_vc(struct vty *, const char *, const char *, + const char *, const char *); int ldp_vty_show_debugging(struct vty *); void ldp_vty_init(void); diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c index cd92958d4c..aa2e06dfb9 100644 --- a/ldpd/ldp_vty_cmds.c +++ b/ldpd/ldp_vty_cmds.c @@ -112,30 +112,52 @@ DEFUN_NOSH(ldp_exit_address_family, return CMD_SUCCESS; } -DEFPY (ldp_discovery_holdtime, - ldp_discovery_holdtime_cmd, - "[no] discovery <hello|targeted-hello>$hello_type holdtime (1-65535)$holdtime", +DEFPY (ldp_discovery_link_holdtime, + ldp_discovery_link_holdtime_cmd, + "[no] discovery hello holdtime (1-65535)$holdtime", NO_STR "Configure discovery parameters\n" "LDP Link Hellos\n" + "Hello holdtime\n" + "Time (seconds) - 65535 implies infinite\n") +{ + return (ldp_vty_disc_holdtime(vty, no, HELLO_LINK, holdtime)); +} + +DEFPY (ldp_discovery_targeted_holdtime, + ldp_discovery_targeted_holdtime_cmd, + "[no] discovery targeted-hello holdtime (1-65535)$holdtime", + NO_STR + "Configure discovery parameters\n" "LDP Targeted Hellos\n" "Hello holdtime\n" "Time (seconds) - 65535 implies infinite\n") { - return (ldp_vty_disc_holdtime(vty, no, hello_type, holdtime)); + return (ldp_vty_disc_holdtime(vty, no, HELLO_TARGETED, holdtime)); } -DEFPY (ldp_discovery_interval, - ldp_discovery_interval_cmd, - "[no] discovery <hello|targeted-hello>$hello_type interval (1-65535)$interval", +DEFPY (ldp_discovery_link_interval, + ldp_discovery_link_interval_cmd, + "[no] discovery hello interval (1-65535)$interval", NO_STR "Configure discovery parameters\n" "LDP Link Hellos\n" + "Hello interval\n" + "Time (seconds)\n") +{ + return (ldp_vty_disc_interval(vty, no, HELLO_LINK, interval)); +} + +DEFPY (ldp_discovery_targeted_interval, + ldp_discovery_targeted_interval_cmd, + "[no] discovery targeted-hello interval (1-65535)$interval", + NO_STR + "Configure discovery parameters\n" "LDP Targeted Hellos\n" "Hello interval\n" "Time (seconds)\n") { - return (ldp_vty_disc_interval(vty, no, hello_type, interval)); + return (ldp_vty_disc_interval(vty, no, HELLO_TARGETED, interval)); } DEFPY (ldp_dual_stack_transport_connection_prefer_ipv4, @@ -581,17 +603,38 @@ DEFPY (ldp_debug_mpls_ldp_messages_sent, DEFPY (ldp_show_mpls_ldp_binding, ldp_show_mpls_ldp_binding_cmd, - "show mpls ldp [<ipv4|ipv6>]$af binding [detail]$detail [json]$json", + "show mpls ldp [<ipv4|ipv6>]$af binding\ + [<A.B.C.D/M|X:X::X:X/M>$prefix [longer-prefixes$longer_prefixes]]\ + [{\ + neighbor A.B.C.D$nbr\ + |local-label (0-1048575)$local_label\ + |remote-label (0-1048575)$remote_label\ + }]\ + [detail]$detail [json]$json", "Show running system information\n" "MPLS information\n" "Label Distribution Protocol\n" "IPv4 Address Family\n" "IPv6 Address Family\n" "Label Information Base (LIB) information\n" + "Destination prefix (IPv4)\n" + "Destination prefix (IPv6)\n" + "Include longer matches\n" + "Display labels from LDP neighbor\n" + "Neighbor LSR-ID\n" + "Match locally assigned label values\n" + "Locally assigned label value\n" + "Match remotely assigned label values\n" + "Remotely assigned label value\n" "Show detailed information\n" JSON_STR) { - return (ldp_vty_show_binding(vty, af, detail, json)); + if (!local_label_str) + local_label = NO_LABEL; + if (!remote_label_str) + remote_label = NO_LABEL; + return (ldp_vty_show_binding(vty, af, prefix_str, !!longer_prefixes, + nbr_str, local_label, remote_label, detail, json)); } DEFPY (ldp_show_mpls_ldp_discovery, @@ -637,52 +680,81 @@ DEFPY (ldp_show_mpls_ldp_capabilities, DEFPY (ldp_show_mpls_ldp_neighbor, ldp_show_mpls_ldp_neighbor_cmd, - "show mpls ldp neighbor [detail]$detail [json]$json", + "show mpls ldp neighbor [A.B.C.D]$lsr_id [detail]$detail [json]$json", "Show running system information\n" "MPLS information\n" "Label Distribution Protocol\n" "Neighbor information\n" + "Neighbor LSR-ID\n" "Show detailed information\n" JSON_STR) { - return (ldp_vty_show_neighbor(vty, 0, detail, json)); + return (ldp_vty_show_neighbor(vty, lsr_id_str, 0, detail, json)); } DEFPY (ldp_show_mpls_ldp_neighbor_capabilities, ldp_show_mpls_ldp_neighbor_capabilities_cmd, - "show mpls ldp neighbor capabilities [json]$json", + "show mpls ldp neighbor [A.B.C.D]$lsr_id capabilities [json]$json", "Show running system information\n" "MPLS information\n" "Label Distribution Protocol\n" "Neighbor information\n" + "Neighbor LSR-ID\n" "Display neighbor capability information\n" JSON_STR) { - return (ldp_vty_show_neighbor(vty, 1, NULL, json)); + return (ldp_vty_show_neighbor(vty, lsr_id_str, 1, NULL, json)); } DEFPY (ldp_show_l2vpn_atom_binding, ldp_show_l2vpn_atom_binding_cmd, - "show l2vpn atom binding [json]$json", + "show l2vpn atom binding\ + [{\ + A.B.C.D$peer\ + |local-label (16-1048575)$local_label\ + |remote-label (16-1048575)$remote_label\ + }]\ + [json]$json", "Show running system information\n" "Show information about Layer2 VPN\n" "Show Any Transport over MPLS information\n" "Show AToM label binding information\n" + "Destination address of the VC\n" + "Match locally assigned label values\n" + "Locally assigned label value\n" + "Match remotely assigned label values\n" + "Remotely assigned label value\n" JSON_STR) { - return (ldp_vty_show_atom_binding(vty, json)); + if (!local_label_str) + local_label = NO_LABEL; + if (!remote_label_str) + remote_label = NO_LABEL; + return (ldp_vty_show_atom_binding(vty, peer_str, local_label, + remote_label, json)); } DEFPY (ldp_show_l2vpn_atom_vc, ldp_show_l2vpn_atom_vc_cmd, - "show l2vpn atom vc [json]$json", + "show l2vpn atom vc\ + [{\ + A.B.C.D$peer\ + |interface IFNAME$ifname\ + |vc-id (1-4294967295)$vcid\ + }]\ + [json]$json", "Show running system information\n" "Show information about Layer2 VPN\n" "Show Any Transport over MPLS information\n" "Show AToM virtual circuit information\n" + "Destination address of the VC\n" + "Local interface of the pseudowire\n" + "Interface's name\n" + "VC ID\n" + "VC ID\n" JSON_STR) { - return (ldp_vty_show_atom_vc(vty, json)); + return (ldp_vty_show_atom_vc(vty, peer_str, ifname, vcid_str, json)); } DEFUN_NOSH (ldp_show_debugging_mpls_ldp, @@ -747,8 +819,10 @@ ldp_vty_init (void) install_element(LDP_NODE, &ldp_address_family_cmd); install_element(LDP_NODE, &no_ldp_address_family_cmd); - install_element(LDP_NODE, &ldp_discovery_holdtime_cmd); - install_element(LDP_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_NODE, &ldp_discovery_targeted_holdtime_cmd); + install_element(LDP_NODE, &ldp_discovery_link_interval_cmd); + install_element(LDP_NODE, &ldp_discovery_targeted_interval_cmd); install_element(LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd); install_element(LDP_NODE, &ldp_dual_stack_cisco_interop_cmd); install_element(LDP_NODE, &ldp_neighbor_password_cmd); @@ -756,8 +830,10 @@ ldp_vty_init (void) install_element(LDP_NODE, &ldp_neighbor_ttl_security_cmd); install_element(LDP_NODE, &ldp_router_id_cmd); - install_element(LDP_IPV4_NODE, &ldp_discovery_holdtime_cmd); - install_element(LDP_IPV4_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_holdtime_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_link_interval_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_interval_cmd); install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd); install_element(LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd); install_element(LDP_IPV4_NODE, &ldp_label_local_advertise_cmd); @@ -771,8 +847,10 @@ ldp_vty_init (void) install_element(LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd); install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd); - install_element(LDP_IPV6_NODE, &ldp_discovery_holdtime_cmd); - install_element(LDP_IPV6_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_holdtime_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_link_interval_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_interval_cmd); install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd); install_element(LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd); install_element(LDP_IPV6_NODE, &ldp_label_local_advertise_cmd); @@ -785,11 +863,11 @@ ldp_vty_init (void) install_element(LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd); install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd); - install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_holdtime_cmd); - install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_interval_cmd); - install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_holdtime_cmd); - install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_interval_cmd); install_element(LDP_L2VPN_NODE, &ldp_bridge_cmd); install_element(LDP_L2VPN_NODE, &ldp_mtu_cmd); diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index e938582d0d..76c602afbb 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -233,6 +233,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf, ldp_af_iface_config_write(vty, af); + vty_out(vty, " !\n"); vty_out(vty, " exit-address-family\n"); } @@ -459,20 +460,13 @@ ldp_vty_address_family(struct vty *vty, const char *negate, const char *af_str) return (CMD_SUCCESS); } -int -ldp_vty_disc_holdtime(struct vty *vty, const char *negate, - const char *hello_type_str, long secs) +int ldp_vty_disc_holdtime(struct vty *vty, const char *negate, + enum hello_type hello_type, long secs) { struct ldpd_af_conf *af_conf; struct iface *iface; struct iface_af *ia; int af; - enum hello_type hello_type; - - if (hello_type_str[0] == 'h') - hello_type = HELLO_LINK; - else - hello_type = HELLO_TARGETED; switch (vty->node) { case LDP_NODE: @@ -547,18 +541,12 @@ ldp_vty_disc_holdtime(struct vty *vty, const char *negate, int ldp_vty_disc_interval(struct vty *vty, const char *negate, - const char *hello_type_str, long secs) + enum hello_type hello_type, long secs) { struct ldpd_af_conf *af_conf; struct iface *iface; struct iface_af *ia; int af; - enum hello_type hello_type; - - if (hello_type_str[0] == 'h') - hello_type = HELLO_LINK; - else - hello_type = HELLO_TARGETED; switch (vty->node) { case LDP_NODE: diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index ad5e79c721..66c127abdc 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -44,9 +44,28 @@ struct show_params { int family; union ldpd_addr addr; uint8_t prefixlen; - int capabilities; int detail; int json; + union { + struct { + struct in_addr lsr_id; + int capabilities; + } neighbor; + struct { + struct prefix prefix; + int longer_prefixes; + struct in_addr neighbor; + uint32_t local_label; + uint32_t remote_label; + } lib; + struct { + struct in_addr peer; + uint32_t local_label; + uint32_t remote_label; + char ifname[IFNAMSIZ]; + uint32_t vcid; + } l2vpn; + }; }; #define LDPBUFSIZ 65535 @@ -1005,6 +1024,12 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) switch (imsg->hdr.type) { case IMSG_CTL_SHOW_LIB_BEGIN: + rt = imsg->data; + + if (params->lib.remote_label != NO_LABEL && + params->lib.remote_label != rt->remote_label) + return (0); + /* FALLTHROUGH */ case IMSG_CTL_SHOW_LIB_RCVD: rt = imsg->data; @@ -1012,9 +1037,6 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) !rt->no_downstream) break; - if (params->family != AF_UNSPEC && params->family != rt->af) - break; - snprintf(dstnet, sizeof(dstnet), "%s/%d", log_addr(rt->af, &rt->prefix), rt->prefixlen); @@ -1039,7 +1061,7 @@ static int show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) { struct ctl_rt *rt = NULL; - char dstnet[BUFSIZ]; + static char dstnet[BUFSIZ]; static int upstream, downstream; size_t buflen; static char sent_buffer[LDPBUFSIZ]; @@ -1047,38 +1069,25 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para switch (imsg->hdr.type) { case IMSG_CTL_SHOW_LIB_BEGIN: - case IMSG_CTL_SHOW_LIB_SENT: - case IMSG_CTL_SHOW_LIB_RCVD: - case IMSG_CTL_SHOW_LIB_END: rt = imsg->data; - if (params->family != AF_UNSPEC && params->family != rt->af) - return (0); - break; - default: - break; - } - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_LIB_BEGIN: upstream = 0; downstream = 0; sent_buffer[0] = '\0'; rcvd_buffer[0] = '\0'; - snprintf(dstnet, sizeof(dstnet), "%s/%d", log_addr(rt->af, &rt->prefix), rt->prefixlen); - - vty_out (vty, "%s\n", dstnet); - vty_out (vty, "%-8sLocal binding: label: %s\n", "", - log_label(rt->local_label)); break; case IMSG_CTL_SHOW_LIB_SENT: + rt = imsg->data; + upstream = 1; buflen = strlen(sent_buffer); snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen, "%12s%s:0\n", "", inet_ntoa(rt->nexthop)); break; case IMSG_CTL_SHOW_LIB_RCVD: + rt = imsg->data; downstream = 1; buflen = strlen(rcvd_buffer); snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen, @@ -1087,6 +1096,14 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para rt->in_use ? " (in use)" : ""); break; case IMSG_CTL_SHOW_LIB_END: + rt = imsg->data; + + if (params->lib.remote_label != NO_LABEL && + !downstream) + break; + vty_out(vty, "%s\n", dstnet); + vty_out(vty, "%-8sLocal binding: label: %s\n", "", + log_label(rt->local_label)); if (upstream) { vty_out (vty, "%-8sAdvertised to:\n", ""); vty_out(vty, "%s", sent_buffer); @@ -1170,19 +1187,8 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params, switch (imsg->hdr.type) { case IMSG_CTL_SHOW_LIB_BEGIN: - case IMSG_CTL_SHOW_LIB_SENT: - case IMSG_CTL_SHOW_LIB_RCVD: - case IMSG_CTL_SHOW_LIB_END: rt = imsg->data; - if (params->family != AF_UNSPEC && params->family != rt->af) - return (0); - break; - default: - break; - } - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_LIB_BEGIN: snprintf(dstnet, sizeof(dstnet), "%s/%d", log_addr(rt->af, &rt->prefix), rt->prefixlen); @@ -1201,12 +1207,16 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params, json_object_object_add(json, dstnet, json_lib_entry); break; case IMSG_CTL_SHOW_LIB_SENT: + rt = imsg->data; + json_adv_label = json_object_new_object(); json_object_string_add(json_adv_label, "neighborId", inet_ntoa(rt->nexthop)); json_object_array_add(json_adv_labels, json_adv_label); break; case IMSG_CTL_SHOW_LIB_RCVD: + rt = imsg->data; + json_remote_label = json_object_new_object(); json_object_string_add(json_remote_label, "neighborId", inet_ntoa(rt->nexthop)); @@ -1410,89 +1420,273 @@ ldp_vty_connect(struct imsgbuf *ibuf) } static int -ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd, +ldp_vty_dispatch_iface(struct vty *vty, struct imsg *imsg, struct show_params *params, json_object *json) { int ret; - switch (cmd) { - case SHOW_IFACE: + if (params->json) + ret = show_interface_msg_json(imsg, params, json); + else + ret = show_interface_msg(vty, imsg, params); + + return (ret); +} + +static int +ldp_vty_dispatch_disc(struct vty *vty, struct imsg *imsg, + struct show_params *params, json_object *json) +{ + int ret; + + if (params->detail) { if (params->json) - ret = show_interface_msg_json(imsg, params, json); + ret = show_discovery_detail_msg_json(imsg, params, + json); else - ret = show_interface_msg(vty, imsg, params); - break; - case SHOW_DISC: - if (params->detail) { - if (params->json) - ret = show_discovery_detail_msg_json(imsg, - params, json); - else - ret = show_discovery_detail_msg(vty, imsg, - params); - } else { - if (params->json) - ret = show_discovery_msg_json(imsg, params, - json); - else - ret = show_discovery_msg(vty, imsg, params); + ret = show_discovery_detail_msg(vty, imsg, params); + } else { + if (params->json) + ret = show_discovery_msg_json(imsg, params, json); + else + ret = show_discovery_msg(vty, imsg, params); + } + + return (ret); +} + +static int +ldp_vty_dispatch_nbr(struct vty *vty, struct imsg *imsg, + struct show_params *params, json_object *json) +{ + static bool filtered = false; + struct ctl_nbr *nbr; + int ret; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_NBR: + filtered = false; + nbr = imsg->data; + + if (params->neighbor.lsr_id.s_addr != INADDR_ANY && + params->neighbor.lsr_id.s_addr != nbr->id.s_addr) { + filtered = true; + return (0); } break; - case SHOW_NBR: - if (params->capabilities) { - if (params->json) - ret = show_nbr_capabilities_msg_json(imsg, - params, json); - else - ret = show_nbr_capabilities_msg(vty, imsg, - params); - } else if (params->detail) { - if (params->json) - ret = show_nbr_detail_msg_json(imsg, params, - json); - else - ret = show_nbr_detail_msg(vty, imsg, params); - } else { - if (params->json) - ret = show_nbr_msg_json(imsg, params, json); - else - ret = show_nbr_msg(vty, imsg, params); - } + case IMSG_CTL_SHOW_NBR_DISC: + case IMSG_CTL_SHOW_NBR_END: + if (filtered) + return (0); break; - case SHOW_LIB: - if (params->detail) { - if (params->json) - ret = show_lib_detail_msg_json(imsg, params, - json); - else - ret = show_lib_detail_msg(vty, imsg, params); - } else { - if (params->json) - ret = show_lib_msg_json(imsg, params, json); - else - ret = show_lib_msg(vty, imsg, params); - } + default: break; - case SHOW_L2VPN_PW: + } + + if (params->neighbor.capabilities) { + if (params->json) + ret = show_nbr_capabilities_msg_json(imsg, params, + json); + else + ret = show_nbr_capabilities_msg(vty, imsg, params); + } else if (params->detail) { + if (params->json) + ret = show_nbr_detail_msg_json(imsg, params, json); + else + ret = show_nbr_detail_msg(vty, imsg, params); + } else { if (params->json) - ret = show_l2vpn_pw_msg_json(imsg, params, json); + ret = show_nbr_msg_json(imsg, params, json); else - ret = show_l2vpn_pw_msg(vty, imsg, params); + ret = show_nbr_msg(vty, imsg, params); + } + + return (ret); +} + +static int +ldp_vty_dispatch_lib(struct vty *vty, struct imsg *imsg, + struct show_params *params, json_object *json) +{ + static bool filtered = false; + struct ctl_rt *rt = NULL; + struct prefix prefix; + int ret; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_LIB_BEGIN: + filtered = false; break; - case SHOW_L2VPN_BINDING: + case IMSG_CTL_SHOW_LIB_SENT: + case IMSG_CTL_SHOW_LIB_RCVD: + case IMSG_CTL_SHOW_LIB_END: + if (filtered) + return (0); + break; + default: + break; + } + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_LIB_BEGIN: + case IMSG_CTL_SHOW_LIB_SENT: + case IMSG_CTL_SHOW_LIB_RCVD: + case IMSG_CTL_SHOW_LIB_END: + rt = imsg->data; + + if (params->family != AF_UNSPEC && params->family != rt->af) { + filtered = true; + return (0); + } + + prefix.family = rt->af; + prefix.prefixlen = rt->prefixlen; + memcpy(&prefix.u.val, &rt->prefix, sizeof(prefix.u.val)); + if (params->lib.prefix.family != AF_UNSPEC) { + if (!params->lib.longer_prefixes && + !prefix_same(¶ms->lib.prefix, &prefix)) { + filtered = true; + return (0); + } else if (params->lib.longer_prefixes && + !prefix_match(¶ms->lib.prefix, &prefix)) { + filtered = true; + return (0); + } + } + + if (params->lib.local_label != NO_LABEL && + params->lib.local_label != rt->local_label) { + filtered = true; + return (0); + } + break; + default: + break; + } + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_LIB_SENT: + case IMSG_CTL_SHOW_LIB_RCVD: + if (params->lib.neighbor.s_addr != INADDR_ANY && + params->lib.neighbor.s_addr != rt->nexthop.s_addr) + return (0); + break; + default: + break; + } + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_LIB_RCVD: + if (params->lib.remote_label != NO_LABEL && + params->lib.remote_label != rt->remote_label) + return (0); + break; + default: + break; + } + + if (params->detail) { if (params->json) - ret = show_l2vpn_binding_msg_json(imsg, params, json); + ret = show_lib_detail_msg_json(imsg, params, json); else - ret = show_l2vpn_binding_msg(vty, imsg, params); + ret = show_lib_detail_msg(vty, imsg, params); + } else { + if (params->json) + ret = show_lib_msg_json(imsg, params, json); + else + ret = show_lib_msg(vty, imsg, params); + } + + return (ret); +} + +static int +ldp_vty_dispatch_l2vpn_pw(struct vty *vty, struct imsg *imsg, + struct show_params *params, json_object *json) +{ + struct ctl_pw *pw; + int ret; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_L2VPN_PW: + pw = imsg->data; + if (params->l2vpn.peer.s_addr != INADDR_ANY && + params->l2vpn.peer.s_addr != pw->lsr_id.s_addr) + return (0); + if (params->l2vpn.ifname[0] != '\0' && + strcmp(params->l2vpn.ifname, pw->ifname)) + return (0); + if (params->l2vpn.vcid && params->l2vpn.vcid != pw->pwid) + return (0); break; default: - return (0); + break; } + if (params->json) + ret = show_l2vpn_pw_msg_json(imsg, params, json); + else + ret = show_l2vpn_pw_msg(vty, imsg, params); + + return (ret); +} + +static int +ldp_vty_dispatch_l2vpn_binding(struct vty *vty, struct imsg *imsg, + struct show_params *params, json_object *json) +{ + struct ctl_pw *pw; + int ret; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_L2VPN_BINDING: + pw = imsg->data; + if (params->l2vpn.peer.s_addr != INADDR_ANY && + params->l2vpn.peer.s_addr != pw->lsr_id.s_addr) + return (0); + if (params->l2vpn.local_label != NO_LABEL && + params->l2vpn.local_label != pw->local_label) + return (0); + if (params->l2vpn.remote_label != NO_LABEL && + params->l2vpn.remote_label != pw->remote_label) + return (0); + break; + default: + break; + } + + if (params->json) + ret = show_l2vpn_binding_msg_json(imsg, params, json); + else + ret = show_l2vpn_binding_msg(vty, imsg, params); + return (ret); } static int +ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd, + struct show_params *params, json_object *json) +{ + switch (cmd) { + case SHOW_IFACE: + return (ldp_vty_dispatch_iface(vty, imsg, params, json)); + case SHOW_DISC: + return (ldp_vty_dispatch_disc(vty, imsg, params, json)); + case SHOW_NBR: + return (ldp_vty_dispatch_nbr(vty, imsg, params, json)); + case SHOW_LIB: + return (ldp_vty_dispatch_lib(vty, imsg, params, json)); + case SHOW_L2VPN_PW: + return (ldp_vty_dispatch_l2vpn_pw(vty, imsg, params, json)); + case SHOW_L2VPN_BINDING: + return (ldp_vty_dispatch_l2vpn_binding(vty, imsg, params, + json)); + default: + return (0); + } +} + +static int ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd, struct show_params *params) { @@ -1565,7 +1759,9 @@ ldp_vty_get_af(const char *str, int *af) } int -ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, const char *json) +ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *prefix, + int longer_prefixes, const char *neighbor, unsigned long local_label, + unsigned long remote_label, const char *detail, const char *json) { struct imsgbuf ibuf; struct show_params params; @@ -1581,6 +1777,18 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, co params.family = af; params.detail = (detail) ? 1 : 0; params.json = (json) ? 1 : 0; + if (prefix) { + (void)str2prefix(prefix, ¶ms.lib.prefix); + params.lib.longer_prefixes = longer_prefixes; + } + if (neighbor && + (inet_pton(AF_INET, neighbor, ¶ms.lib.neighbor) != 1 || + bad_addr_v4(params.lib.neighbor))) { + vty_out (vty, "%% Malformed address\n"); + return (CMD_SUCCESS); + } + params.lib.local_label = local_label; + params.lib.remote_label = remote_label; if (!params.detail && !params.json) vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF", @@ -1703,7 +1911,8 @@ ldp_vty_show_capabilities(struct vty *vty, const char *json) } int -ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, const char *json) +ldp_vty_show_neighbor(struct vty *vty, const char *lsr_id, int capabilities, + const char *detail, const char *json) { struct imsgbuf ibuf; struct show_params params; @@ -1712,11 +1921,17 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con return (CMD_WARNING); memset(¶ms, 0, sizeof(params)); - params.capabilities = capabilities; params.detail = (detail) ? 1 : 0; params.json = (json) ? 1 : 0; + params.neighbor.capabilities = capabilities; + if (lsr_id && + (inet_pton(AF_INET, lsr_id, ¶ms.neighbor.lsr_id) != 1 || + bad_addr_v4(params.neighbor.lsr_id))) { + vty_out (vty, "%% Malformed address\n"); + return (CMD_SUCCESS); + } - if (params.capabilities) + if (params.neighbor.capabilities) params.detail = 1; if (!params.detail && !params.json) @@ -1728,7 +1943,8 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con } int -ldp_vty_show_atom_binding(struct vty *vty, const char *json) +ldp_vty_show_atom_binding(struct vty *vty, const char *peer, + unsigned long local_label, unsigned long remote_label, const char *json) { struct imsgbuf ibuf; struct show_params params; @@ -1738,13 +1954,22 @@ ldp_vty_show_atom_binding(struct vty *vty, const char *json) memset(¶ms, 0, sizeof(params)); params.json = (json) ? 1 : 0; + if (peer && + (inet_pton(AF_INET, peer, ¶ms.l2vpn.peer) != 1 || + bad_addr_v4(params.l2vpn.peer))) { + vty_out (vty, "%% Malformed address\n"); + return (CMD_SUCCESS); + } + params.l2vpn.local_label = local_label; + params.l2vpn.remote_label = remote_label; imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0); return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, ¶ms)); } int -ldp_vty_show_atom_vc(struct vty *vty, const char *json) +ldp_vty_show_atom_vc(struct vty *vty, const char *peer, const char *ifname, + const char *vcid, const char *json) { struct imsgbuf ibuf; struct show_params params; @@ -1754,6 +1979,17 @@ ldp_vty_show_atom_vc(struct vty *vty, const char *json) memset(¶ms, 0, sizeof(params)); params.json = (json) ? 1 : 0; + if (peer && + (inet_pton(AF_INET, peer, ¶ms.l2vpn.peer) != 1 || + bad_addr_v4(params.l2vpn.peer))) { + vty_out (vty, "%% Malformed address\n"); + return (CMD_SUCCESS); + } + if (ifname) + strlcpy(params.l2vpn.ifname, ifname, + sizeof(params.l2vpn.ifname)); + if (vcid) + params.l2vpn.vcid = atoi(vcid); if (!params.json) { /* header */ diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index d31c575920..12aeb1fff3 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -206,7 +206,7 @@ main(int argc, char *argv[]) frr_preinit(&ldpd_di, argc, argv); frr_opt_add("LEn:", longopts, " --ctl_socket Override ctl socket path\n" - "-n, --instance Instance id\n"); + " -n, --instance Instance id\n"); while (1) { int opt; @@ -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); @@ -435,7 +434,7 @@ static pid_t start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) { char *argv[3]; - int argc = 0; + int argc = 0, nullfd; pid_t pid; switch (pid = fork()) { @@ -449,6 +448,17 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) return (pid); } + 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); + } + if (dup2(fd_async, LDPD_FD_ASYNC) == -1) fatal("cannot setup imsg async fd"); if (dup2(fd_sync, LDPD_FD_SYNC) == -1) 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); @@ -367,7 +367,7 @@ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag, json_bfd); } else { vty_out(vty, - " %s%sDetect Mul: %d, Min Rx interval: %d," + " %s%sDetect Multiplier: %d, Min Rx interval: %d," " Min Tx interval: %d\n", (extra_space) ? " " : "", (bfd_tag) ? "BFD: " : " ", bfd_info->detect_mult, bfd_info->required_min_rx, 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); } } } @@ -191,8 +191,8 @@ void if_delete(struct interface *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); @@ -1095,8 +1095,7 @@ void if_terminate(struct list **intf_list) if_delete(ifp); } - list_delete(*intf_list); - *intf_list = NULL; + list_delete_and_null(intf_list); } const char *if_link_type_str(enum zebra_link_type llt) 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 d5078f98aa..6cb8711edf 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -534,7 +534,7 @@ struct thread_master *frr_init(void) snprintf(p_pathspace, sizeof(p_pathspace), "/%s", di->pathspace); - snprintf(config_default, sizeof(config_default), "%s%s/%s%s.conf", + snprintf(config_default, sizeof(config_default), "%s%s%s%s.conf", frr_sysconfdir, p_pathspace, di->name, p_instance); snprintf(pidfile_default, sizeof(pidfile_default), "%s%s/%s%s.pid", frr_vtydir, p_pathspace, di->name, p_instance); @@ -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/sha256.c b/lib/sha256.c index a1b77901ee..37ced5b402 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -192,7 +192,8 @@ static void SHA256_Transform(uint32_t *state, const unsigned char block[64]) /* Clean the stack. */ memset(W, 0, 256); memset(S, 0, 32); - t0 = t1 = 0; + memset(&t0, 0, sizeof(t0)); + memset(&t1, 0, sizeof(t0)); } static unsigned char PAD[64] = { 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); 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/zclient.c b/lib/zclient.c index e30f166dde..43d46a1801 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); } } @@ -1619,7 +1618,7 @@ static int zclient_read_sync_response(struct zclient *zclient, u_int16_t expected_cmd) { struct stream *s; - u_int16_t size; + u_int16_t size = -1; u_char marker; u_char version; vrf_id_t vrf_id; 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_interface.c b/ospf6d/ospf6_interface.c index 8e01cb4379..7286b3242d 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); 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_route.c b/ospf6d/ospf6_route.c index e58eab2b15..5b78dda688 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); } } @@ -1469,13 +1469,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 +1496,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 +1516,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_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..b0281b9e0a 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); diff --git a/ospfd/.gitignore b/ospfd/.gitignore index 752c875a62..018a363a93 100644 --- a/ospfd/.gitignore +++ b/ospfd/.gitignore @@ -15,3 +15,4 @@ TAGS *~ *.loT *.a +*.clippy.c diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 968461b4d0..f7aa94ad18 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -91,7 +91,7 @@ static void ospf_area_range_delete(struct ospf_area *area, struct ospf_area_range *range = rn->info; if (range->specifics != 0) - ospf_delete_discard_route(area->ospf->new_table, + ospf_delete_discard_route(area->ospf, area->ospf->new_table, (struct prefix_ipv4 *)&rn->p); ospf_area_range_free(range); @@ -1684,12 +1684,12 @@ static void ospf_abr_manage_discard_routes(struct ospf *ospf) if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)) { if (range->specifics) - ospf_add_discard_route( + ospf_add_discard_route(ospf, ospf->new_table, area, (struct prefix_ipv4 *)&rn->p); else - ospf_delete_discard_route( + ospf_delete_discard_route(ospf, ospf->new_table, (struct prefix_ipv4 *)&rn->p); diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index a5f5971ac0..8c1ad5ff0c 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -80,9 +80,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_addr(struct in_addr address) { struct listnode *node, *nnode; struct ospf_interface *oi; - struct ospf *ospf; + struct ospf *ospf = NULL; - if (!(ospf = ospf_lookup())) + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) return NULL; for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) @@ -97,9 +98,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp) { struct listnode *node, *nnode; struct ospf_interface *oi; - struct ospf *ospf; + struct ospf *ospf = NULL; - if (!(ospf = ospf_lookup())) + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) return NULL; for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) @@ -178,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 */ @@ -999,7 +1001,7 @@ void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv) struct ospf_interface *oi; struct registered_opaque_type *r; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { /* Check if this interface is indeed ready for type 9 */ @@ -1047,7 +1049,7 @@ void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv) struct ospf *ospf; struct ospf_area *area; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { struct registered_opaque_type *r; @@ -1094,7 +1096,7 @@ void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv) struct ospf *ospf; struct registered_opaque_type *r; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Can type 11 be originated? */ if (!ospf_apiserver_is_ready_type11(ospf)) @@ -1271,7 +1273,7 @@ int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv, struct ospf *ospf; struct ospf_area *area; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Get request sequence number */ seqnum = msg_get_seq(msg); @@ -1374,7 +1376,11 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area, struct ospf *ospf; - ospf = ospf_lookup(); + if (oi && oi->ospf) + ospf = oi->ospf; + else + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + assert(ospf); /* Create a stream for internal opaque LSA */ @@ -1429,6 +1435,7 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area, new->area = area; new->oi = oi; + new->vrf_id = ospf->vrf_id; SET_FLAG(new->flags, OSPF_LSA_SELF); memcpy(new->data, newlsa, length); @@ -1497,7 +1504,7 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv, int ready = 0; int rc = 0; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Extract opaque LSA data from message */ omsg = (struct msg_originate_request *)STREAM_DATA(msg->s); @@ -1640,7 +1647,7 @@ void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa) case OSPF_OPAQUE_AS_LSA: { struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); assert(ospf); /* Increment counters? XXX */ @@ -1656,7 +1663,7 @@ int ospf_apiserver_originate1(struct ospf_lsa *lsa) { struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); assert(ospf); /* Install this LSA into LSDB. */ @@ -1726,7 +1733,7 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa) struct ospf_lsa *new = NULL; struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); assert(ospf); apiserv = lookup_apiserver_by_lsa(lsa); @@ -1810,7 +1817,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv, int rc = 0; struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); assert(ospf); /* Extract opaque LSA from message */ @@ -1862,7 +1869,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv, * the LSDB until it is finally handled by the maxage remover thread. * Therefore, the lookup function below may return non-NULL result. */ - old = ospf_lsa_lookup(area, dmsg->lsa_type, id, ospf->router_id); + old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id); if (!old) { zlog_warn( "ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB", @@ -1923,7 +1930,7 @@ void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv, struct ospf *ospf; struct ospf_area *area; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); assert(ospf); /* Set parameter struct. */ @@ -2315,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_asbr.c b/ospfd/ospf_asbr.c index e3b66d597b..89c462693b 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -58,7 +58,8 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p) /* Remove route from zebra. */ if (or->type == OSPF_DESTINATION_NETWORK) - ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, + ospf_zebra_delete(ospf, + (struct prefix_ipv4 *)&rn->p, or); ospf_route_free(or); diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index bf2b809ddc..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; } @@ -598,7 +598,8 @@ static int ospf_ase_route_match_same(struct route_table *rt, return 1; } -static int ospf_ase_compare_tables(struct route_table *new_external_route, +static int ospf_ase_compare_tables(struct ospf *ospf, + struct route_table *new_external_route, struct route_table *old_external_route) { struct route_node *rn, *new_rn; @@ -609,7 +610,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route, if ((or = rn->info)) { if (!(new_rn = route_node_lookup(new_external_route, &rn->p))) - ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, + ospf_zebra_delete(ospf, + (struct prefix_ipv4 *)&rn->p, or); else route_unlock_node(new_rn); @@ -621,7 +623,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route, if ((or = rn->info) != NULL) if (!ospf_ase_route_match_same(old_external_route, &rn->p, or)) - ospf_zebra_add((struct prefix_ipv4 *)&rn->p, + ospf_zebra_add(ospf, + (struct prefix_ipv4 *)&rn->p, or); return 0; @@ -666,7 +669,7 @@ static int ospf_ase_calculate_timer(struct thread *t) /* Compare old and new external routing table and install the difference info zebra/kernel */ - ospf_ase_compare_tables(ospf->new_external_route, + ospf_ase_compare_tables(ospf, ospf->new_external_route, ospf->old_external_route); /* Delete old external routing table */ @@ -758,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); @@ -814,7 +817,7 @@ void ospf_ase_incremental_update(struct ospf *ospf, struct ospf_lsa *lsa) } /* install changes to zebra */ - ospf_ase_compare_tables(ospf->new_external_route, tmp_old); + ospf_ase_compare_tables(ospf, ospf->new_external_route, tmp_old); /* update ospf->old_external_route table */ if (rn && rn->info) diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index 6d07b44364..9254e7d240 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -75,12 +75,13 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command) bfd_info = (struct bfd_info *)params->bfd_info; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("%s nbr (%s) with BFD", + zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s", bfd_get_command_dbg_str(command), - inet_ntoa(nbr->src)); + inet_ntoa(nbr->src), + ospf_vrf_id_to_name(oi->ospf->vrf_id)); bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name, - 0, 0, command, 0, VRF_DEFAULT); + 0, 0, command, 0, oi->ospf->vrf_id); } /* @@ -158,7 +159,7 @@ static int ospf_bfd_nbr_replay(int command, struct zclient *zclient, /* Send the client registration */ bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); - /* Replay the neighbor, if BFD is enabled in BGP */ + /* Replay the neighbor, if BFD is enabled in OSPF */ for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) { for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) { if ((nbrs = oi->nbrs) == NULL) diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 619bd4e5f5..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) { @@ -1604,9 +1605,10 @@ DEFUN_NOSH (show_debugging_ospf, DEBUG_STR OSPF_STR) { - struct ospf *ospf; + struct ospf *ospf = NULL; - if ((ospf = ospf_lookup()) == NULL) + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL) return CMD_SUCCESS; return show_debugging_ospf_common(vty, ospf); @@ -1651,7 +1653,8 @@ static int config_write_debug(struct vty *vty) char str[16]; memset(str, 0, 16); - if ((ospf = ospf_lookup()) == NULL) + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL) return CMD_SUCCESS; if (ospf->instance) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index c775f2ea2e..aac2f3ee92 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -77,7 +77,8 @@ static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr, } /* Check LSA is related to external info. */ -struct external_info *ospf_external_info_check(struct ospf_lsa *lsa) +struct external_info *ospf_external_info_check(struct ospf *ospf, + struct ospf_lsa *lsa) { struct as_external_lsa *al; struct prefix_ipv4 p; @@ -96,11 +97,11 @@ struct external_info *ospf_external_info_check(struct ospf_lsa *lsa) redist_on = is_prefix_default(&p) ? vrf_bitmap_check(zclient->default_information, - VRF_DEFAULT) + ospf->vrf_id) : (zclient->mi_redist[AFI_IP][type].enabled || vrf_bitmap_check( zclient->redist[AFI_IP][type], - VRF_DEFAULT)); + ospf->vrf_id)); // Pending: check for MI above. if (redist_on) { struct list *ext_list; @@ -205,7 +206,7 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf, ospf_translated_nssa_refresh(ospf, NULL, new); return; } - ei = ospf_external_info_check(new); + ei = ospf_external_info_check(ospf, new); if (ei) ospf_external_lsa_refresh(ospf, new, ei, LSA_REFRESH_FORCE); diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h index b74894567d..6f7ecfccf0 100644 --- a/ospfd/ospf_flood.h +++ b/ospfd/ospf_flood.h @@ -61,7 +61,8 @@ extern void ospf_flood_lsa_as(struct ospf_lsa *); extern void ospf_lsa_flush_area(struct ospf_lsa *, struct ospf_area *); extern void ospf_lsa_flush_as(struct ospf *, struct ospf_lsa *); extern void ospf_lsa_flush(struct ospf *, struct ospf_lsa *); -extern struct external_info *ospf_external_info_check(struct ospf_lsa *); +extern struct external_info *ospf_external_info_check(struct ospf *, + struct ospf_lsa *); extern void ospf_lsdb_init(struct ospf_lsdb *); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 422e1a2a6b..67ce6f1713 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -243,6 +243,11 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp, oi->ospf = ospf; QOBJ_REG(oi, ospf_interface); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ospf interface %s vrf %s id %u created", + __PRETTY_FUNCTION__, ifp->name, + ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id); + return oi; } @@ -308,10 +313,16 @@ 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_delete_and_null(&oi->ls_ack); + list_delete_and_null(&oi->ls_ack_direct.ls_ack); - list_free(oi->ls_ack); - list_free(oi->ls_ack_direct.ls_ack); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ospf interface %s vrf %s id %u deleted", + __PRETTY_FUNCTION__, oi->ifp->name, + ospf_vrf_id_to_name(oi->ifp->vrf_id), + oi->ifp->vrf_id); ospf_delete_from_if(oi->ifp, oi); @@ -335,7 +346,11 @@ struct ospf_interface *ospf_if_exists(struct ospf_interface *oic) struct ospf *ospf; struct ospf_interface *oi; - if ((ospf = ospf_lookup()) == NULL) + if (!oic) + return NULL; + + ospf = oic->ospf; + if (ospf == NULL) return NULL; for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) @@ -494,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); } @@ -800,10 +815,11 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_vl_new(): creating pseudo zebra interface"); + zlog_debug("ospf_vl_new(): creating pseudo zebra interface vrf id %u", + ospf->vrf_id); snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count); - vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT); + vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id); /* * if_create sets ZEBRA_INTERFACE_LINKDETECTION * virtual links don't need this. @@ -1164,7 +1180,6 @@ u_char ospf_default_iftype(struct interface *ifp) void ospf_if_init() { /* Initialize Zebra interface data structure. */ - om->iflist = vrf_iflist(VRF_DEFAULT); hook_register_prio(if_add, 0, ospf_if_new_hook); hook_register_prio(if_del, 0, ospf_if_delete_hook); } 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 68adf2e10b..74d5178f55 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -161,6 +161,7 @@ struct ospf_lsa *ospf_lsa_new() monotime(&new->tv_recv); new->tv_orig = new->tv_recv; new->refresh_list = -1; + new->vrf_id = VRF_DEFAULT; return new; } @@ -786,6 +787,7 @@ static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area) new->area = area; SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + new->vrf_id = area->ospf->vrf_id; /* Copy LSA data to store, discard stream. */ new->data = ospf_lsa_data_new(length); @@ -1001,6 +1003,7 @@ static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi) new->area = oi->area; SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + new->vrf_id = oi->ospf->vrf_id; /* Copy LSA to store. */ new->data = ospf_lsa_data_new(length); @@ -1180,6 +1183,7 @@ static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area, new = ospf_lsa_new(); new->area = area; SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + new->vrf_id = area->ospf->vrf_id; /* Copy LSA to store. */ new->data = ospf_lsa_data_new(length); @@ -1321,6 +1325,7 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area, new = ospf_lsa_new(); new->area = area; SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + new->vrf_id = area->ospf->vrf_id; /* Copy LSA to store. */ new->data = ospf_lsa_data_new(length); @@ -1627,6 +1632,7 @@ static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf, new->area = NULL; SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED); + new->vrf_id = ospf->vrf_id; /* Copy LSA data to store, discard stream. */ new->data = ospf_lsa_data_new(length); @@ -1696,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 @@ -2121,14 +2127,15 @@ int ospf_default_originate_timer(struct thread *thread) void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p) { struct listnode *node, *nnode; - struct ospf_lsa *lsa; + struct ospf_lsa *lsa = NULL; struct ospf_area *area; for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { if (area->external_routing == OSPF_AREA_NSSA) { - if (!(lsa = ospf_lsa_lookup(area, OSPF_AS_NSSA_LSA, - p->prefix, - ospf->router_id))) { + lsa = ospf_lsa_lookup(ospf, area, + OSPF_AS_NSSA_LSA, p->prefix, + ospf->router_id); + if (!lsa) { if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( "LSA: There is no such AS-NSSA-LSA %s/%d in LSDB", @@ -2844,11 +2851,12 @@ static int ospf_maxage_lsa_remover(struct thread *thread) void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa) { struct route_node *rn; - struct prefix_ptr lsa_prefix; + struct prefix lsa_prefix; + memset(&lsa_prefix, 0, sizeof(struct prefix)); lsa_prefix.family = 0; - lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT; - lsa_prefix.prefix = (uintptr_t)lsa; + lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT; + lsa_prefix.u.ptr = (uintptr_t)lsa; if ((rn = route_node_lookup(ospf->maxage_lsa, (struct prefix *)&lsa_prefix))) { @@ -2860,6 +2868,10 @@ void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa) rn); /* unlock node because lsa is deleted */ } route_unlock_node(rn); /* route_node_lookup */ + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: lsa %s is not found in maxage db.", + __PRETTY_FUNCTION__, dump_lsa_key(lsa)); } } @@ -2870,7 +2882,7 @@ void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa) */ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa) { - struct prefix_ptr lsa_prefix; + struct prefix lsa_prefix; struct route_node *rn; /* When we saw a MaxAge LSA flooded to us, we put it on the list @@ -2884,9 +2896,10 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa) return; } + memset(&lsa_prefix, 0, sizeof(struct prefix)); lsa_prefix.family = 0; - lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT; - lsa_prefix.prefix = (uintptr_t)lsa; + lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT; + lsa_prefix.u.ptr = (uintptr_t)lsa; if ((rn = route_node_get(ospf->maxage_lsa, (struct prefix *)&lsa_prefix)) @@ -2903,7 +2916,8 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa) SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE); } } else { - zlog_err("Unable to allocate memory for maxage lsa\n"); + zlog_err("Unable to allocate memory for maxage lsa %s\n", + dump_lsa_key(lsa)); assert(0); } @@ -3039,11 +3053,12 @@ struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, u_char type, return lsa; } -struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *area, u_int32_t type, - struct in_addr id, struct in_addr adv_router) +struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area, + u_int32_t type, struct in_addr id, + struct in_addr adv_router) { - struct ospf *ospf = ospf_lookup(); - assert(ospf); + if (!ospf) + return NULL; switch (type) { case OSPF_ROUTER_LSA: @@ -3113,7 +3128,8 @@ struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area, * they two were forming a unique LSA-ID. */ - match = ospf_lsa_lookup(area, lsah->type, lsah->id, lsah->adv_router); + match = ospf_lsa_lookup(area->ospf, area, lsah->type, lsah->id, + lsah->adv_router); if (match == NULL) if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA) @@ -3529,7 +3545,7 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa) */ if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) break; - ei = ospf_external_info_check(lsa); + ei = ospf_external_info_check(ospf, lsa); if (ei) new = ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE); @@ -3606,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 */ @@ -3675,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); } } @@ -3691,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_lsa.h b/ospfd/ospf_lsa.h index ab8e62b6e4..94a34d4a90 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -111,6 +111,9 @@ struct ospf_lsa { /* For Type-9 Opaque-LSAs */ struct ospf_interface *oi; + + /* VRF Id */ + vrf_id_t vrf_id; }; /* OSPF LSA Link Type. */ @@ -267,8 +270,9 @@ extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *, struct external_info *); extern int ospf_external_lsa_originate_timer(struct thread *); extern int ospf_default_originate_timer(struct thread *); -extern struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *, u_int32_t, - struct in_addr, struct in_addr); +extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *, + u_int32_t, struct in_addr, + struct in_addr); extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, u_int32_t, struct in_addr); extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *, diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index f284a04cbe..7bd644f43d 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -187,7 +187,7 @@ int main(int argc, char **argv) /* Library inits. */ debug_init(); - vrf_init(NULL, NULL, NULL, NULL); + ospf_vrf_init(); access_list_init(); prefix_list_init(); diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index c72c69856c..699f2341d5 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -153,7 +153,10 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex) if (ret < 0) zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", top->fd, safe_strerror(errno)); - +#ifndef GNU_LINUX + /* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send + * packet out of ifindex. Below would be used Non Linux system. + */ ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex); if (ret < 0) zlog_warn( @@ -161,23 +164,53 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex) "ifindex %u): %s", top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); +#endif return ret; } -int ospf_sock_init(void) +int ospf_bind_vrfdevice(struct ospf *ospf, int ospf_sock) +{ + int ret = 0; + +#ifdef SO_BINDTODEVICE + + if (ospf && ospf->vrf_id != VRF_DEFAULT && + ospf->vrf_id != VRF_UNKNOWN) { + ret = setsockopt(ospf_sock, SOL_SOCKET, SO_BINDTODEVICE, + ospf->name, + strlen(ospf->name)); + if (ret < 0) { + int save_errno = errno; + + zlog_warn("%s: Could not setsockopt SO_BINDTODEVICE %s", + __PRETTY_FUNCTION__, + safe_strerror(save_errno)); + } else { + zlog_debug("%s: Bind socket %d to vrf %s id %u device", + __PRETTY_FUNCTION__, ospf_sock, + ospf->name, ospf->vrf_id); + } + } +#endif + return ret; +} + +int ospf_sock_init(struct ospf *ospf) { int ospf_sock; int ret, hincl = 1; int bufsize = (8 * 1024 * 1024); - if (ospfd_privs.change(ZPRIVS_RAISE)) + if (ospfd_privs.change(ZPRIVS_RAISE)) { zlog_err("ospf_sock_init: could not raise privs, %s", safe_strerror(errno)); + } ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP); if (ospf_sock < 0) { int save_errno = errno; + if (ospfd_privs.change(ZPRIVS_LOWER)) zlog_err("ospf_sock_init: could not lower privs, %s", safe_strerror(errno)); @@ -186,17 +219,23 @@ int ospf_sock_init(void) exit(1); } + ret = ospf_bind_vrfdevice(ospf, ospf_sock); + if (ret < 0) { + close(ospf_sock); + goto out; + } + #ifdef IP_HDRINCL /* we will include IP header with packet */ ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl)); if (ret < 0) { int save_errno = errno; - if (ospfd_privs.change(ZPRIVS_LOWER)) - zlog_err("ospf_sock_init: could not lower privs, %s", - safe_strerror(errno)); + 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) #warning "IP_HDRINCL not available on this system" @@ -204,13 +243,11 @@ int ospf_sock_init(void) ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL); if (ret < 0) { int save_errno = errno; - if (ospfd_privs.change(ZPRIVS_LOWER)) - zlog_err("ospf_sock_init: could not lower privs, %s", - safe_strerror(errno)); + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, ospf_sock, safe_strerror(save_errno)); close(ospf_sock); /* Prevent sd leak. */ - return ret; + goto out; } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" @@ -222,13 +259,14 @@ int ospf_sock_init(void) if (ret < 0) zlog_warn("Can't set pktinfo option for fd %d", ospf_sock); + setsockopt_so_sendbuf(ospf_sock, bufsize); + setsockopt_so_recvbuf(ospf_sock, bufsize); + + ospf->fd = ospf_sock; +out: if (ospfd_privs.change(ZPRIVS_LOWER)) { zlog_err("ospf_sock_init: could not lower privs, %s", safe_strerror(errno)); } - - setsockopt_so_sendbuf(ospf_sock, bufsize); - setsockopt_so_recvbuf(ospf_sock, bufsize); - - return ospf_sock; + return ret; } diff --git a/ospfd/ospf_network.h b/ospfd/ospf_network.h index ed5e00315c..41a7abda70 100644 --- a/ospfd/ospf_network.h +++ b/ospfd/ospf_network.h @@ -29,6 +29,7 @@ extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *, extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t); extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t); extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t); -extern int ospf_sock_init(void); +extern int ospf_sock_init(struct ospf *ospf); +extern int ospf_bind_vrfdevice(struct ospf *, int); #endif /* _ZEBRA_OSPF_NETWORK_H */ diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index db523bd2a4..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; } @@ -544,7 +542,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab, listnode_add(new->area->opaque_lsa_self, oipt); break; case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(new->vrf_id); if (new->area != NULL && (top = new->area->ospf) == NULL) { free_opaque_info_per_type((void *)oipt); oipt = NULL; @@ -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; } @@ -648,7 +646,7 @@ lookup_opaque_info_by_type(struct ospf_lsa *lsa) "Type-10 Opaque-LSA: Reference to AREA is missing?"); break; case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(lsa->vrf_id); if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) { zlog_warn( "Type-11 Opaque-LSA: Reference to OSPF is missing?"); @@ -1571,7 +1569,7 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc) } break; case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(lsa->vrf_id); if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) { /* Above conditions must have passed. */ zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?"); @@ -1597,7 +1595,7 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa) struct ospf_opaque_functab *functab; struct ospf_lsa *new = NULL; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(lsa->vrf_id); if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL || functab->lsa_refresher == NULL) { @@ -1638,7 +1636,7 @@ static int ospf_opaque_lsa_refresh_timer(struct thread *t); void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, u_char lsa_type, u_char opaque_type) { - struct ospf *top; + struct ospf *top = NULL; struct ospf_area dummy, *area = NULL; struct ospf_interface *oi = NULL; @@ -1739,6 +1737,7 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, /* Generate a dummy lsa to be passed for a lookup function. */ lsa = pseudo_lsa(oi, area, lsa_type, opaque_type); + lsa->vrf_id = top->vrf_id; if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) { struct ospf_opaque_functab *functab; @@ -1804,6 +1803,7 @@ static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi, lsa.oi = oi; lsa.area = area; lsa.data = &lsah; + lsa.vrf_id = VRF_DEFAULT; lsah.type = lsa_type; tmp = SET_OPAQUE_LSID(opaque_type, 0); /* Opaque-ID is unused here. */ @@ -2000,7 +2000,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa); break; case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(lsa0->vrf_id); if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) top = lsa0->area->ospf; ospf_ls_retransmit_delete_nbr_as(top, lsa); @@ -2054,7 +2054,7 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0) struct ospf_lsa *lsa; struct ospf *top; - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(lsa0->vrf_id); if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL || (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) { diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 36f9a6757a..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. */ @@ -649,6 +649,12 @@ static int ospf_write(struct thread *thread) #define OSPF_WRITE_IPHL_SHIFT 2 int pkt_count = 0; +#ifdef GNU_LINUX + unsigned char cmsgbuf[64] = {}; + struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf; + struct in_pktinfo *pi; +#endif + ospf->t_write = NULL; node = listhead(ospf->oi_write_q); @@ -753,14 +759,28 @@ static int ospf_write(struct thread *thread) msg.msg_namelen = sizeof(sa_dst); msg.msg_iov = iov; msg.msg_iovlen = 2; + iov[0].iov_base = (char *)&iph; iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT; iov[1].iov_base = STREAM_PNT(op->s); iov[1].iov_len = op->length; -/* Sadly we can not rely on kernels to fragment packets because of either - * IP_HDRINCL and/or multicast destination being set. - */ +#ifdef GNU_LINUX + msg.msg_control = (caddr_t)cm; + cm->cmsg_level = SOL_IP; + cm->cmsg_type = IP_PKTINFO; + cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + pi = (struct in_pktinfo *)CMSG_DATA(cm); + pi->ipi_ifindex = oi->ifp->ifindex; + + msg.msg_controllen = cm->cmsg_len; +#endif + + /* Sadly we can not rely on kernels to fragment packets + * because of either IP_HDRINCL and/or multicast + * destination being set. + */ + #ifdef WANT_OSPF_WRITE_FRAGMENT if (op->length > maxdatasize) ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize, @@ -907,9 +927,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Packet %s [Hello:RECV]: Options %s", + zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s", inet_ntoa(ospfh->router_id), - ospf_options_dump(hello->options)); + ospf_options_dump(hello->options), + ospf_vrf_id_to_name(oi->ospf->vrf_id)); /* Compare options. */ #define REJECT_IF_TBIT_ON 1 /* XXX */ @@ -1551,15 +1572,16 @@ 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; } /* Search proper LSA in LSDB. */ - find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router); + find = ospf_lsa_lookup(oi->ospf, oi->area, ls_type, ls_id, + adv_router); if (find == NULL) { OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); - list_delete(ls_upd); + list_delete_and_null(&ls_upd); return; } @@ -1593,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. @@ -1696,6 +1718,7 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, /* Create OSPF LSA instance. */ lsa = ospf_lsa_new(); + lsa->vrf_id = oi->ospf->vrf_id; /* We may wish to put some error checking if type NSSA comes in and area not in NSSA mode */ switch (lsah->type) { @@ -1735,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. */ @@ -1784,6 +1807,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, */ lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size); + if (lsas == NULL) + return; #define DISCARD_LSA(L, N) \ { \ if (IS_DEBUG_OSPF_EVENT) \ @@ -2134,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. */ @@ -2173,6 +2198,7 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, lsa = ospf_lsa_new(); lsa->data = (struct lsa_header *)STREAM_PNT(s); + lsa->vrf_id = oi->ospf->vrf_id; /* lsah = (struct lsa_header *) STREAM_PNT (s); */ size -= OSPF_LSA_HEADER_SIZE; @@ -2197,7 +2223,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, return; } -static struct stream *ospf_recv_packet(int fd, struct interface **ifp, +static struct stream *ospf_recv_packet(struct ospf *ospf, int fd, + struct interface **ifp, struct stream *ibuf) { int ret; @@ -2265,7 +2292,7 @@ static struct stream *ospf_recv_packet(int fd, struct interface **ifp, ifindex = getsockopt_ifindex(AF_INET, &msgh); - *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); + *ifp = if_lookup_by_index(ifindex, ospf->vrf_id); if (ret != ip_len) { zlog_warn( @@ -2833,7 +2860,7 @@ int ospf_read(struct thread *thread) struct ip *iph; struct ospf_header *ospfh; u_int16_t length; - struct interface *ifp; + struct interface *ifp = NULL; struct connected *c; /* first of all get interface pointer. */ @@ -2844,7 +2871,8 @@ int ospf_read(struct thread *thread) thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read); stream_reset(ospf->ibuf); - if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf))) + ibuf = ospf_recv_packet(ospf, ospf->fd, &ifp, ospf->ibuf); + if (ibuf == NULL) return -1; /* This raw packet is known to be at least as big as its IP header. */ @@ -2861,7 +2889,7 @@ int ospf_read(struct thread *thread) ifindex retrieval but do not. */ c = if_lookup_address((void *)&iph->ip_src, AF_INET, - VRF_DEFAULT); + ospf->vrf_id); if (c) ifp = c->ifp; if (ifp == NULL) @@ -3487,6 +3515,13 @@ static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr) op->dst.s_addr = addr; + if (IS_DEBUG_OSPF_EVENT) { + if (oi->ospf->vrf_id) + zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u", + __PRETTY_FUNCTION__, oi->ifp->name, + ospf_vrf_id_to_name(oi->ospf->vrf_id), + oi->ospf->vrf_id); + } /* Add packet to the top of the interface output queue, so that they * can't get delayed by things like long queues of LS Update packets */ @@ -3739,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 @@ -3883,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; @@ -4065,21 +4099,19 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi) * punt-to-CPU set on them. This may overload the CPU control path that * can be avoided if the MAC was known apriori. */ -#define OSPF_PING_NBR_STR_MAX (8 + 40 + 20) +#define OSPF_PING_NBR_STR_MAX (BUFSIZ) void ospf_proactively_arp(struct ospf_neighbor *nbr) { char ping_nbr[OSPF_PING_NBR_STR_MAX]; - char *str_ptr; int ret; if (!nbr || !nbr->oi || !nbr->oi->ifp) return; - str_ptr = strcpy(ping_nbr, "ping -c 1 -I "); - str_ptr = strcat(str_ptr, nbr->oi->ifp->name); - str_ptr = strcat(str_ptr, " "); - str_ptr = strcat(str_ptr, inet_ntoa(nbr->address.u.prefix4)); - str_ptr = strcat(str_ptr, " > /dev/null 2>&1 &"); + snprintf(ping_nbr, sizeof(ping_nbr), + "ping -c 1 -I %s %s > /dev/null 2>&1 &", + nbr->oi->ifp->name, inet_ntoa(nbr->address.u.prefix4)); + ret = system(ping_nbr); if (IS_DEBUG_OSPF_EVENT) zlog_debug("Executed %s %s", ping_nbr, diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 13013bf8ca..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(); @@ -427,7 +425,7 @@ static void initialize_params(struct ospf_router_info *ori) /* If Area address is not null and exist, retrieve corresponding * structure */ - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(VRF_DEFAULT); zlog_info("RI-> Initialize Router Info for %s scope within area %s", OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", inet_ntoa(OspfRI.area_id)); @@ -586,7 +584,7 @@ static struct ospf_lsa *ospf_router_info_lsa_new() "LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance", lsa_type, inet_ntoa(lsa_id)); - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Set opaque-LSA header fields. */ lsa_header_set(s, options, lsa_type, lsa_id, top->router_id); @@ -615,6 +613,11 @@ static struct ospf_lsa *ospf_router_info_lsa_new() new->area = OspfRI.area; /* Area must be null if the Opaque type is AS scope, fulfill otherwise */ + if (new->area && new->area->ospf) + new->vrf_id = new->area->ospf->vrf_id; + else + new->vrf_id = VRF_DEFAULT; + SET_FLAG(new->flags, OSPF_LSA_SELF); memcpy(new->data, lsah, length); stream_free(s); @@ -628,6 +631,7 @@ static int ospf_router_info_lsa_originate1(void *arg) struct ospf *top; struct ospf_area *area; int rc = -1; + vrf_id_t vrf_id = VRF_DEFAULT; /* First check if the area is known if flooding scope is Area */ if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) { @@ -638,6 +642,8 @@ static int ospf_router_info_lsa_originate1(void *arg) return rc; } OspfRI.area = area; + if (area->ospf) + vrf_id = area->ospf->vrf_id; } /* Create new Opaque-LSA/ROUTER INFORMATION instance. */ @@ -646,9 +652,16 @@ static int ospf_router_info_lsa_originate1(void *arg) "ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?"); return rc; } + new->vrf_id = vrf_id; /* Get ospf info */ - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(vrf_id); + if (top == NULL) { + zlog_debug("%s: ospf instance not found for vrf id %u", + __PRETTY_FUNCTION__, vrf_id); + ospf_lsa_unlock(&new); + return rc; + } /* Install this LSA into LSDB. */ if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { @@ -751,10 +764,11 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa) return NULL; } new->data->ls_seqnum = lsa_seqnum_increment(lsa); + new->vrf_id = lsa->vrf_id; /* Install this LSA into LSDB. */ /* Given "lsa" will be freed in the next function. */ - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(lsa->vrf_id); if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?"); ospf_lsa_unlock(&new); @@ -800,7 +814,7 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode) if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode == REORIGINATE_THIS_LSA)) opcode = REFRESH_THIS_LSA; - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(VRF_DEFAULT); if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) { zlog_warn( "ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set"); diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 89ea331b52..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); } @@ -83,7 +83,7 @@ void ospf_path_free(struct ospf_path *op) XFREE(MTYPE_OSPF_PATH, op); } -void ospf_route_delete(struct route_table *rt) +void ospf_route_delete(struct ospf *ospf, struct route_table *rt) { struct route_node *rn; struct ospf_route * or ; @@ -91,10 +91,11 @@ void ospf_route_delete(struct route_table *rt) for (rn = route_top(rt); rn; rn = route_next(rn)) if ((or = rn->info) != NULL) { if (or->type == OSPF_DESTINATION_NETWORK) - ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, + ospf_zebra_delete(ospf, + (struct prefix_ipv4 *)&rn->p, or); else if (or->type == OSPF_DESTINATION_DISCARD) - ospf_zebra_delete_discard( + ospf_zebra_delete_discard(ospf, (struct prefix_ipv4 *)&rn->p); } } @@ -191,7 +192,8 @@ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix, /* delete routes generated from AS-External routes if there is a inter/intra * area route */ -static void ospf_route_delete_same_ext(struct route_table *external_routes, +static void ospf_route_delete_same_ext(struct ospf *ospf, + struct route_table *external_routes, struct route_table *routes) { struct route_node *rn, *ext_rn; @@ -206,7 +208,8 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes, if ((ext_rn = route_node_lookup(external_routes, (struct prefix *)p))) { if (ext_rn->info) { - ospf_zebra_delete(p, ext_rn->info); + ospf_zebra_delete(ospf, p, + ext_rn->info); ospf_route_free(ext_rn->info); ext_rn->info = NULL; } @@ -217,7 +220,7 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes, } /* rt: Old, cmprt: New */ -static void ospf_route_delete_uniq(struct route_table *rt, +static void ospf_route_delete_uniq(struct ospf *ospf, struct route_table *rt, struct route_table *cmprt) { struct route_node *rn; @@ -232,7 +235,7 @@ static void ospf_route_delete_uniq(struct route_table *rt, cmprt, (struct prefix_ipv4 *)&rn ->p)) - ospf_zebra_delete( + ospf_zebra_delete(ospf, (struct prefix_ipv4 *)&rn->p, or); @@ -241,7 +244,7 @@ static void ospf_route_delete_uniq(struct route_table *rt, cmprt, (struct prefix_ipv4 *)&rn ->p)) - ospf_zebra_delete_discard( + ospf_zebra_delete_discard(ospf, (struct prefix_ipv4 *)&rn->p); } @@ -263,9 +266,9 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt) /* Delete old routes. */ if (ospf->old_table) - ospf_route_delete_uniq(ospf->old_table, rt); + ospf_route_delete_uniq(ospf, ospf->old_table, rt); if (ospf->old_external_route) - ospf_route_delete_same_ext(ospf->old_external_route, rt); + ospf_route_delete_same_ext(ospf, ospf->old_external_route, rt); /* Install new routes. */ for (rn = route_top(rt); rn; rn = route_next(rn)) @@ -274,14 +277,14 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt) if (!ospf_route_match_same( ospf->old_table, (struct prefix_ipv4 *)&rn->p, or)) - ospf_zebra_add( + ospf_zebra_add(ospf, (struct prefix_ipv4 *)&rn->p, or); } else if (or->type == OSPF_DESTINATION_DISCARD) if (!ospf_route_match_same( ospf->old_table, (struct prefix_ipv4 *)&rn->p, or)) - ospf_zebra_add_discard( + ospf_zebra_add_discard(ospf, (struct prefix_ipv4 *)&rn->p); } } @@ -899,14 +902,15 @@ 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); } } } -int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area, +int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt, + struct ospf_area *area, struct prefix_ipv4 *p) { struct route_node *rn; @@ -961,12 +965,13 @@ int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area, new_or->path_type = OSPF_PATH_INTER_AREA; rn->info = new_or; - ospf_zebra_add_discard(p); + ospf_zebra_add_discard(ospf, p); return 1; } -void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p) +void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt, + struct prefix_ipv4 *p) { struct route_node *rn; struct ospf_route * or ; @@ -1012,7 +1017,7 @@ void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p) route_unlock_node(rn); /* remove the discard entry from the rib */ - ospf_zebra_delete_discard(p); + ospf_zebra_delete_discard(ospf, p); return; } diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index 1999379844..76df54fb3f 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -115,7 +115,7 @@ extern void ospf_path_free(struct ospf_path *); extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *); extern struct ospf_route *ospf_route_new(void); extern void ospf_route_free(struct ospf_route *); -extern void ospf_route_delete(struct route_table *); +extern void ospf_route_delete(struct ospf *, struct route_table *); extern void ospf_route_table_free(struct route_table *); extern void ospf_route_install(struct ospf *, struct route_table *); @@ -145,9 +145,9 @@ extern void ospf_route_add(struct route_table *, struct prefix_ipv4 *, extern void ospf_route_subst_nexthops(struct ospf_route *, struct list *); extern void ospf_prune_unreachable_networks(struct route_table *); extern void ospf_prune_unreachable_routers(struct route_table *); -extern int ospf_add_discard_route(struct route_table *, struct ospf_area *, - struct prefix_ipv4 *); -extern void ospf_delete_discard_route(struct route_table *, +extern int ospf_add_discard_route(struct ospf *, struct route_table *, + struct ospf_area *, struct prefix_ipv4 *); +extern void ospf_delete_discard_route(struct ospf *, struct route_table *, struct prefix_ipv4 *); extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *, struct ospf_route *); diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index f47e2b6f1e..b7a47602d0 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -45,38 +45,40 @@ static void ospf_route_map_update(const char *name) { struct ospf *ospf; int type; + struct listnode *n1 = NULL; /* If OSPF instatnce does not exist, return right now. */ - ospf = ospf_lookup(); - if (ospf == NULL) + if (listcount(om->ospf) == 0) return; - /* Update route-map */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (!red_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { - if (ROUTEMAP_NAME(red) - && strcmp(ROUTEMAP_NAME(red), name) == 0) { - /* Keep old route-map. */ - struct route_map *old = ROUTEMAP(red); - - /* Update route-map. */ - ROUTEMAP(red) = route_map_lookup_by_name( - ROUTEMAP_NAME(red)); - - /* No update for this distribute type. */ - if (old == NULL && ROUTEMAP(red) == NULL) - continue; - - ospf_distribute_list_update(ospf, type, - red->instance); + for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + /* Update route-map */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (!red_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP_NAME(red) + && strcmp(ROUTEMAP_NAME(red), name) == 0) { + /* Keep old route-map. */ + struct route_map *old = ROUTEMAP(red); + + /* Update route-map. */ + ROUTEMAP(red) = route_map_lookup_by_name( + ROUTEMAP_NAME(red)); + + /* No update for this distribute type. */ + if (old == NULL && ROUTEMAP(red) == NULL) + continue; + + ospf_distribute_list_update(ospf, type, + red->instance); + } } } } @@ -86,26 +88,24 @@ static void ospf_route_map_event(route_map_event_t event, const char *name) { struct ospf *ospf; int type; - - /* If OSPF instatnce does not exist, return right now. */ - ospf = ospf_lookup(); - if (ospf == NULL) - return; - - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (!red_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { - if (ROUTEMAP_NAME(red) && ROUTEMAP(red) - && !strcmp(ROUTEMAP_NAME(red), name)) { - ospf_distribute_list_update(ospf, type, - red->instance); + struct listnode *n1 = NULL; + + for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (!red_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP_NAME(red) && ROUTEMAP(red) + && !strcmp(ROUTEMAP_NAME(red), name)) { + ospf_distribute_list_update(ospf, type, + red->instance); + } } } } @@ -285,7 +285,7 @@ static route_map_result_t route_match_interface(void *rule, if (type == RMAP_OSPF) { ei = object; - ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT); + ifp = if_lookup_by_name_all_vrf((char *)rule); if (ifp == NULL || ifp->ifindex != ei->ifindex) return RMAP_NOMATCH; diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 6a352380b8..36ae091f99 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -532,7 +532,7 @@ static u_char *ospfGeneralGroup(struct variable *v, oid *name, size_t *length, { struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Check whether the instance identifier is valid */ if (smux_header_generic(v, name, length, exact, var_len, write_method) @@ -661,7 +661,7 @@ static struct ospf_area *ospfAreaLookup(struct variable *v, oid name[], struct ospf_area *area; int len; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -765,7 +765,7 @@ static struct ospf_area *ospf_stub_area_lookup_next(struct in_addr *area_id, struct listnode *node; struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -792,7 +792,7 @@ static struct ospf_area *ospfStubAreaLookup(struct variable *v, oid name[], struct ospf_area *area; int len; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -934,7 +934,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, oid *offset; int offsetlen; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); #define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE) @@ -1084,7 +1084,7 @@ static u_char *ospfLsdbEntry(struct variable *v, oid *name, size_t *length, memset(&router_id, 0, sizeof(struct in_addr)); /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -1145,7 +1145,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (exact) { /* Area ID + Range Network. */ @@ -1239,7 +1239,7 @@ static u_char *ospfAreaRangeEntry(struct variable *v, oid *name, size_t *length, return NULL; /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -1290,7 +1290,7 @@ static struct ospf_nbr_nbma *ospfHostLookup(struct variable *v, oid *name, struct ospf_nbr_nbma *nbr_nbma; struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -1347,7 +1347,7 @@ static u_char *ospfHostEntry(struct variable *v, oid *name, size_t *length, return NULL; /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -1504,7 +1504,7 @@ static struct ospf_interface *ospf_snmp_if_lookup(struct in_addr *ifaddr, struct listnode *node; struct ospf_snmp_if *osif; struct ospf_interface *oi = NULL; - struct ospf *ospf = ospf_lookup(); + struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) { if (ifaddr->s_addr) { @@ -1527,7 +1527,7 @@ static struct ospf_interface *ospf_snmp_if_lookup_next(struct in_addr *ifaddr, { struct ospf_snmp_if *osif; struct listnode *nn; - struct ospf *ospf = ospf_lookup(); + struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); struct ospf_interface *oi = NULL; if (ospf == NULL) @@ -1675,7 +1675,7 @@ static u_char *ospfIfEntry(struct variable *v, oid *name, size_t *length, memset(&ifaddr, 0, sizeof(struct in_addr)); /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -1845,7 +1845,7 @@ static u_char *ospfIfMetricEntry(struct variable *v, oid *name, size_t *length, memset(&ifaddr, 0, sizeof(struct in_addr)); /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -2125,7 +2125,7 @@ static struct ospf_neighbor *ospf_snmp_nbr_lookup_next(struct in_addr *nbr_addr, struct ospf_neighbor *min = NULL; struct ospf *ospf = ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, nn, oi)) { for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) @@ -2165,7 +2165,7 @@ static struct ospf_neighbor *ospfNbrLookup(struct variable *v, oid *name, struct ospf_neighbor *nbr; struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (!ospf) return NULL; @@ -2325,7 +2325,7 @@ static u_char *ospfVirtNbrEntry(struct variable *v, oid *name, size_t *length, memset(&neighbor, 0, sizeof(struct in_addr)); /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; @@ -2379,7 +2379,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, struct ospf_lsa *lsa; struct ospf *ospf; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (exact) { if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE) return NULL; @@ -2476,7 +2476,7 @@ static u_char *ospfExtLsdbEntry(struct variable *v, oid *name, size_t *length, memset(&router_id, 0, sizeof(struct in_addr)); /* Check OSPF instance. */ - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL) return NULL; diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 891088ecc2..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; @@ -781,7 +779,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area, * of candidates with any vertices not already on the list. If a lower-cost * path is found to a vertex already on the candidate list, store the new cost. */ -static void ospf_spf_next(struct vertex *v, struct ospf_area *area, +static void ospf_spf_next(struct vertex *v, struct ospf *ospf, + struct ospf_area *area, struct pqueue *candidate) { struct ospf_lsa *w_lsa = NULL; @@ -841,7 +840,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area, inet_ntoa(l->link_id)); } - w_lsa = ospf_lsa_lookup(area, OSPF_ROUTER_LSA, + w_lsa = ospf_lsa_lookup(ospf, area, + OSPF_ROUTER_LSA, l->link_id, l->link_id); if (w_lsa) { if (IS_DEBUG_OSPF_EVENT) @@ -1087,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; @@ -1159,7 +1159,7 @@ ospf_rtrs_print (struct route_table *rtrs) #endif /* Calculating the shortest-path tree for an area. */ -static void ospf_spf_calculate(struct ospf_area *area, +static void ospf_spf_calculate(struct ospf *ospf, struct ospf_area *area, struct route_table *new_table, struct route_table *new_rtrs) { @@ -1209,7 +1209,7 @@ static void ospf_spf_calculate(struct ospf_area *area, for (;;) { /* RFC2328 16.1. (2). */ - ospf_spf_next(v, area, candidate); + ospf_spf_next(v, ospf, area, candidate); /* RFC2328 16.1. (3). */ /* If at this step the candidate list is empty, the shortest- @@ -1307,13 +1307,13 @@ static int ospf_spf_calculate_timer(struct thread *thread) if (ospf->backbone && ospf->backbone == area) continue; - ospf_spf_calculate(area, new_table, new_rtrs); + ospf_spf_calculate(ospf, area, new_table, new_rtrs); areas_processed++; } /* SPF for backbone, if required */ if (ospf->backbone) { - ospf_spf_calculate(ospf->backbone, new_table, new_rtrs); + ospf_spf_calculate(ospf, ospf->backbone, new_table, new_rtrs); areas_processed++; } @@ -1339,6 +1339,12 @@ static int ospf_spf_calculate_timer(struct thread *thread) ospf_ase_calculate_timer_add(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ospf install new route, vrf %s id %u new_table count %lu", + __PRETTY_FUNCTION__, + ospf_vrf_id_to_name(ospf->vrf_id), + ospf->vrf_id, new_table->count); /* Update routing table. */ monotime(&start_time); ospf_route_install(ospf, new_table); diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 5517008909..392df5fb40 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); @@ -728,7 +727,7 @@ static void update_linkparams(struct mpls_te_link *lp) else { lp->flags = INTER_AS | FLOOD_AREA; lp->area = ospf_area_lookup_by_area_id( - ospf_lookup(), + ospf_lookup_by_vrf_id(VRF_DEFAULT), OspfMplsTE.interas_areaid); } } @@ -1127,7 +1126,8 @@ static void ospf_mpls_te_lsa_body_set(struct stream *s, struct mpls_te_link *lp) } /* Create new opaque-LSA. */ -static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area, +static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf, + struct ospf_area *area, struct mpls_te_link *lp) { struct stream *s; @@ -1167,9 +1167,12 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area, tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance); lsa_id.s_addr = htonl(tmp); - struct ospf *top = ospf_lookup(); + if (!ospf) { + stream_free(s); + return NULL; + } - lsa_header_set(s, options, lsa_type, lsa_id, top->router_id); + lsa_header_set(s, options, lsa_type, lsa_id, ospf->router_id); } else { options |= LSA_OPTIONS_GET(area); /* Get area default option */ options |= LSA_OPTIONS_NSSA_GET(area); @@ -1207,6 +1210,9 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area, return new; } + new->vrf_id = ospf->vrf_id; + if (area && area->ospf) + new->vrf_id = area->ospf->vrf_id; new->area = area; SET_FLAG(new->flags, OSPF_LSA_SELF); memcpy(new->data, lsah, length); @@ -1218,11 +1224,12 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area, static int ospf_mpls_te_lsa_originate1(struct ospf_area *area, struct mpls_te_link *lp) { - struct ospf_lsa *new; + struct ospf_lsa *new = NULL; int rc = -1; /* Create new Opaque-LSA/MPLS-TE instance. */ - if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) { + new = ospf_mpls_te_lsa_new(area->ospf, area, lp); + if (new == NULL) { zlog_warn( "ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?"); return rc; @@ -1321,11 +1328,13 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top, int rc = -1; /* Create new Opaque-LSA/Inter-AS instance. */ - if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) { + new = ospf_mpls_te_lsa_new(top, NULL, lp); + if (new == NULL) { zlog_warn( "ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?"); return rc; } + new->vrf_id = top->vrf_id; /* Install this LSA into LSDB. */ if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { @@ -1451,9 +1460,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa) ospf_opaque_lsa_flush_schedule(lsa); return NULL; } - + top = ospf_lookup_by_vrf_id(lsa->vrf_id); /* Create new Opaque-LSA/MPLS-TE instance. */ - if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) { + new = ospf_mpls_te_lsa_new(top, area, lp); + if (new == NULL) { zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?"); return NULL; } @@ -1465,8 +1475,6 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa) * ospf_lookup() to get ospf instance */ if (area) top = area->ospf; - else - top = ospf_lookup(); if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?"); @@ -1500,7 +1508,7 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode) memset(&lsa, 0, sizeof(lsa)); memset(&lsah, 0, sizeof(lsah)); - top = ospf_lookup(); + top = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Check if the pseudo link is ready to flood */ if (!(CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE)) @@ -2517,29 +2525,64 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp) DEFUN (show_ip_ospf_mpls_te_link, show_ip_ospf_mpls_te_link_cmd, - "show ip ospf mpls-te interface [INTERFACE]", + "show ip ospf [vrf <NAME|all>] mpls-te interface [INTERFACE]", SHOW_STR IP_STR OSPF_STR + VRF_CMD_HELP_STR + "All VRFs\n" "MPLS-TE information\n" "Interface information\n" "Interface name\n") { int idx_interface = 5; struct interface *ifp; - struct listnode *node, *nnode; - + struct listnode *node, *nnode, *n1; + char *vrf_name = NULL; + bool all_vrf; + int inst = 0; + int idx_vrf = 0; + struct ospf *ospf = NULL; + + if (argv_find(argv, argc, "vrf", &idx_vrf)) { + vrf_name = argv[idx_vrf + 1]->arg; + all_vrf = strmatch(vrf_name, "all"); + } + + /* 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)) { + if (!ospf->oi_running) + continue; + for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), + node, nnode, ifp)) + show_mpls_te_link_sub(vty, ifp); + } + return CMD_SUCCESS; + } + 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)) + show_mpls_te_link_sub(vty, ifp); + return CMD_SUCCESS; + } /* Show All Interfaces. */ if (argc == 5) { - for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, - ifp)) - show_mpls_te_link_sub(vty, ifp); + for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + if (!ospf->oi_running) + continue; + for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, + nnode, ifp)) + show_mpls_te_link_sub(vty, ifp); + } } /* Interface name is specified. */ else { - if ((ifp = if_lookup_by_name(argv[idx_interface]->arg, - VRF_DEFAULT)) - == NULL) + ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg); + if (ifp == NULL) vty_out(vty, "No such interface name\n"); else show_mpls_te_link_sub(vty, ifp); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 4cbd4b4a99..7b7a53baa9 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -126,25 +126,82 @@ int ospf_oi_count(struct interface *ifp) return i; } +#define OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \ + if (argv_find(argv, argc, "vrf", &idx_vrf)) { \ + vrf_name = argv[idx_vrf + 1]->arg; \ + all_vrf = strmatch(vrf_name, "all"); \ + } + +static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty, + struct cmd_token *argv[], + const int argc, + uint32_t enable, + u_short *instance) +{ + struct ospf *ospf = NULL; + int idx_vrf = 0; + const char *vrf_name = NULL; + + if (argv_find(argv, argc, "vrf", &idx_vrf)) { + vrf_name = argv[idx_vrf + 1]->arg; + if (enable) { + if (argc > 4) + *instance = strtoul(argv[2]->arg, NULL, 10); + /* Allocate VRF aware instance */ + ospf = ospf_get(*instance, vrf_name); + } else { + if (argc > 5) + *instance = strtoul(argv[3]->arg, NULL, 10); + ospf = ospf_lookup_by_inst_name(*instance, vrf_name); + } + } else { + if (enable) { + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) + vty_out(vty, + "There isn't active ospf instance\n"); + if (argc > 2) + *instance = strtoul(argv[2]->arg, NULL, 10); + } else { + if (argc > 3) + *instance = strtoul(argv[3]->arg, NULL, 10); + ospf = ospf_lookup_instance(*instance); + } + } + 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 + DEFUN_NOSH (router_ospf, router_ospf_cmd, - "router ospf [(1-65535)]", + "router ospf [{(1-65535)|vrf NAME}]", "Enable a routing process\n" "Start OSPF configuration\n" - "Instance ID\n") + "Instance ID\n" + VRF_CMD_HELP_STR) { - struct ospf *ospf; - u_short instance = 0; + struct ospf *ospf = NULL; int ret = CMD_SUCCESS; + u_short instance = 0; - ospf = ospf_lookup(); - if (!ospf) { - vty_out(vty, "There isn't active ospf instance \n"); + ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance); + if (!ospf) return CMD_WARNING_CONFIG_FAILED; - } - - if (argc > 2) - instance = strtoul(argv[2]->arg, NULL, 10); /* The following logic to set the vty qobj index is in place to be able to ignore the commands which dont belong to this instance. */ @@ -152,10 +209,12 @@ DEFUN_NOSH (router_ospf, VTY_PUSH_CONTEXT_NULL(OSPF_NODE); ret = CMD_NOT_MY_INSTANCE; } else { + if (ospf->vrf_id != VRF_UNKNOWN) + ospf->oi_running = 1; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Config command 'router ospf %d' received", - instance); - ospf->oi_running = 1; + zlog_debug("Config command 'router ospf %d' received, vrf %s id %d oi_running %u", + instance, ospf->name ? ospf->name : "NIL", + ospf->vrf_id, ospf->oi_running); VTY_PUSH_CONTEXT(OSPF_NODE, ospf); ospf_router_id_update(ospf); } @@ -165,29 +224,30 @@ DEFUN_NOSH (router_ospf, DEFUN (no_router_ospf, no_router_ospf_cmd, - "no router ospf [(1-65535)]", + "no router ospf [{(1-65535)|vrf NAME}]", NO_STR "Enable a routing process\n" "Start OSPF configuration\n" - "Instance ID\n") + "Instance ID\n" + VRF_CMD_HELP_STR) { struct ospf *ospf; u_short instance = 0; - if (argc > 3) - instance = strtoul(argv[3]->arg, NULL, 10); - - ospf = ospf_lookup_instance(instance); - if (ospf == NULL) - return CMD_NOT_MY_INSTANCE; - + ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance); + if (ospf == NULL) { + if (instance) + return CMD_NOT_MY_INSTANCE; + else + return CMD_WARNING; + } ospf_finish(ospf); return CMD_SUCCESS; } -DEFUN (ospf_router_id, +DEFPY (ospf_router_id, ospf_router_id_cmd, "ospf router-id A.B.C.D", "OSPF specific commands\n" @@ -195,17 +255,9 @@ DEFUN (ospf_router_id, "OSPF router-id in IP address format\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; + struct listnode *node; struct ospf_area *area; - struct in_addr router_id; - int ret; - - ret = inet_aton(argv[idx_ipv4]->arg, &router_id); - if (!ret) { - vty_out(vty, "Please specify Router ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } ospf->router_id_static = router_id; @@ -256,7 +308,7 @@ DEFUN_HIDDEN (ospf_router_id_old, return CMD_SUCCESS; } -DEFUN (no_ospf_router_id, +DEFPY (no_ospf_router_id, no_ospf_router_id_cmd, "no ospf router-id [A.B.C.D]", NO_STR @@ -268,6 +320,13 @@ DEFUN (no_ospf_router_id, struct listnode *node; struct ospf_area *area; + if (router_id_str) { + if (!IPV4_ADDR_SAME(&ospf->router_id_static, &router_id)) { + vty_out(vty, "%% OSPF router-id doesn't match\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + ospf->router_id_static.s_addr = 0; for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) @@ -292,7 +351,7 @@ static void ospf_passive_interface_default(struct ospf *ospf, u_char newval) ospf->passive_interface_default = newval; - for (ALL_LIST_ELEMENTS_RO(om->iflist, ln, ifp)) { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), ln, ifp)) { if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), passive_interface)) UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface); @@ -366,7 +425,12 @@ DEFUN (ospf_passive_interface, return CMD_SUCCESS; } - ifp = if_get_by_name(argv[1]->arg, VRF_DEFAULT); + ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id); + if (ifp == NULL) { + vty_out(vty, "interface %s not found.\n", + (char *)argv[1]->arg); + return CMD_WARNING; + } params = IF_DEF_PARAMS(ifp); @@ -433,7 +497,12 @@ DEFUN (no_ospf_passive_interface, return CMD_SUCCESS; } - ifp = if_get_by_name(argv[2]->arg, VRF_DEFAULT); + ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id); + if (ifp == NULL) { + vty_out(vty, "interface %s not found.\n", + (char *)argv[1]->arg); + return CMD_WARNING; + } params = IF_DEF_PARAMS(ifp); @@ -963,26 +1032,23 @@ static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config) #define VLINK_HELPSTR_AUTH_SIMPLE \ "Authentication password (key)\n" \ - "The OSPF password (key)" + "The OSPF password (key)\n" #define VLINK_HELPSTR_AUTH_MD5 \ "Message digest authentication password (key)\n" \ - "dummy string \n" \ "Key ID\n" \ "Use MD5 algorithm\n" \ - "The OSPF password (key)" + "The OSPF password (key)\n" DEFUN (ospf_area_vlink, ospf_area_vlink_cmd, - "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]", + "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]", VLINK_HELPSTR_IPADDR - "Enable authentication on this virtual link\n" \ - "Use null authentication\n" \ + "Enable authentication on this virtual link\n" "Use message-digest authentication\n" - "Message digest authentication password (key)\n" \ - "Key ID\n" \ - "Use MD5 algorithm\n" \ - "The OSPF password (key)") + "Use null authentication\n" + VLINK_HELPSTR_AUTH_MD5 + VLINK_HELPSTR_AUTH_SIMPLE) { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); int idx_ipv4_number = 1; @@ -990,8 +1056,8 @@ DEFUN (ospf_area_vlink, struct ospf_vl_config_data vl_config; char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1]; char md5_key[OSPF_AUTH_MD5_SIZE + 1]; - int i; int ret; + int idx = 0; ospf_vl_config_data_init(&vl_config, vty); @@ -1015,80 +1081,36 @@ DEFUN (ospf_area_vlink, return ospf_vl_set(ospf, &vl_config); } - /* Deal with other parameters */ - for (i = 5; i < argc; i++) { - - /* vty_out (vty, "argv[%d]->arg - %s\n", i, argv[i]->text); */ - - switch (argv[i]->arg[0]) { - - case 'a': - if (i > 5 - || strncmp(argv[i]->arg, "authentication-", 15) - == 0) { - /* authentication-key - this option can occur - anywhere on - command line. At start - of command line - must check for - authentication option. */ - memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); - strncpy(auth_key, argv[i + 1]->text, - OSPF_AUTH_SIMPLE_SIZE); - vl_config.auth_key = auth_key; - i++; - } else if (strncmp(argv[i]->arg, "authentication", 14) - == 0) { - /* authentication - this option can only occur - at start - of command line */ - vl_config.auth_type = OSPF_AUTH_SIMPLE; - if ((i + 1) < argc) { - if (strncmp(argv[i + 1]->arg, "n", 1) - == 0) { - /* "authentication null" */ - vl_config.auth_type = - OSPF_AUTH_NULL; - i++; - } else if ( - strncmp(argv[i + 1]->arg, "m", - 1) - == 0 - && !strmatch( - argv[i + 1]->text, - "message-digest-")) { - /* "authentication - * message-digest" */ - vl_config.auth_type = - OSPF_AUTH_CRYPTOGRAPHIC; - i++; - } - } - } - break; + if (argv_find(argv, argc, "authentication", &idx)) { + /* authentication - this option can only occur + at start of command line */ + vl_config.auth_type = OSPF_AUTH_SIMPLE; + } - case 'm': - /* message-digest-key */ - i++; - if (i < argc) { - vl_config.crypto_key_id = - strtol(argv[i]->arg, NULL, 10); - if (vl_config.crypto_key_id < 0) - return CMD_WARNING_CONFIG_FAILED; - i++; - if (i < argc) { - memset(md5_key, 0, - OSPF_AUTH_MD5_SIZE + 1); - strncpy(md5_key, argv[i]->arg, - OSPF_AUTH_MD5_SIZE); - vl_config.md5_key = md5_key; - } - } else - vl_config.md5_key = NULL; - break; - } + if (argv_find(argv, argc, "message-digest", &idx)) { + /* authentication message-digest */ + vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC; + } else if (argv_find(argv, argc, "null", &idx)) { + /* "authentication null" */ + vl_config.auth_type = OSPF_AUTH_NULL; } + if (argv_find(argv, argc, "message-digest-key", &idx)) { + vl_config.md5_key = NULL; + vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10); + if (vl_config.crypto_key_id < 0) + return CMD_WARNING_CONFIG_FAILED; + + memset(md5_key, 0, OSPF_AUTH_MD5_SIZE + 1); + strncpy(md5_key, argv[idx + 3]->arg, OSPF_AUTH_MD5_SIZE); + vl_config.md5_key = md5_key; + } + + if (argv_find(argv, argc, "authentication-key", &idx)) { + memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); + strncpy(auth_key, argv[idx + 1]->arg, OSPF_AUTH_SIMPLE_SIZE); + vl_config.auth_key = auth_key; + } /* Action configuration */ @@ -1097,16 +1119,14 @@ DEFUN (ospf_area_vlink, DEFUN (no_ospf_area_vlink, no_ospf_area_vlink_cmd, - "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]", + "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]", NO_STR VLINK_HELPSTR_IPADDR "Enable authentication on this virtual link\n" \ + "Use message-digest authentication\n" \ "Use null authentication\n" \ - "Use message-digest authentication\n" - "Message digest authentication password (key)\n" \ - "Key ID\n" \ - "Use MD5 algorithm\n" \ - "The OSPF password (key)") + VLINK_HELPSTR_AUTH_MD5 + VLINK_HELPSTR_AUTH_SIMPLE) { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); int idx_ipv4_number = 2; @@ -1115,7 +1135,7 @@ DEFUN (no_ospf_area_vlink, struct ospf_vl_config_data vl_config; struct ospf_vl_data *vl_data = NULL; char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1]; - int i; + int idx = 0; int ret, format; ospf_vl_config_data_init(&vl_config, vty); @@ -1151,50 +1171,26 @@ DEFUN (no_ospf_area_vlink, } /* If we are down here, we are reseting parameters */ - /* Deal with other parameters */ - for (i = 6; i < argc; i++) { - /* vty_out (vty, "argv[%d] - %s\n", i, argv[i]); */ - - switch (argv[i]->arg[0]) { - - case 'a': - if (i > 2 - || strncmp(argv[i]->text, "authentication-", 15) - == 0) { - /* authentication-key - this option can occur - anywhere on - command line. At start - of command line - must check for - authentication option. */ - memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); - vl_config.auth_key = auth_key; - } else if (strncmp(argv[i]->text, "authentication", 14) - == 0) { - /* authentication - this option can only occur - at start - of command line */ - vl_config.auth_type = OSPF_AUTH_NOTSET; - } - break; - case 'm': - /* message-digest-key */ - /* Delete one key */ - i++; - if (i < argc) { - vl_config.crypto_key_id = - strtol(argv[i]->arg, NULL, 10); - if (vl_config.crypto_key_id < 0) - return CMD_WARNING_CONFIG_FAILED; - vl_config.md5_key = NULL; - } else - return CMD_WARNING_CONFIG_FAILED; - break; - } + if (argv_find(argv, argc, "authentication", &idx)) { + /* authentication - this option can only occur + at start of command line */ + vl_config.auth_type = OSPF_AUTH_NOTSET; } + if (argv_find(argv, argc, "message-digest-key", &idx)) { + vl_config.md5_key = NULL; + vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10); + if (vl_config.crypto_key_id < 0) + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv_find(argv, argc, "authentication-key", &idx)) { + /* Reset authentication-key to 0 */ + memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); + vl_config.auth_key = auth_key; + } /* Action configuration */ @@ -2489,7 +2485,7 @@ DEFUN (ospf_auto_cost_reference_bandwidth, return CMD_SUCCESS; ospf->ref_bandwidth = refbw; - for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) ospf_if_recalculate_output_cost(ifp); return CMD_SUCCESS; @@ -2515,7 +2511,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(om->iflist, node, nnode, ifp)) + for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, nnode, ifp)) ospf_if_recalculate_output_cost(ifp); return CMD_SUCCESS; @@ -2906,6 +2902,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", @@ -3175,19 +3173,52 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf, show_ip_ospf_cmd, - "show ip ospf [json]", + "show ip ospf [vrf <NAME|all>] [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" JSON_STR) { struct ospf *ospf; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + if (listcount(om->ospf) == 0) return CMD_SUCCESS; - return (show_ip_ospf_common(vty, ospf, uj)); + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_common(vty, ospf, uj); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if ((ospf == NULL) || !ospf->oi_running) + return CMD_SUCCESS; + } else { + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + /* Display default ospf (instance 0) info */ + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } + + if (ospf) + show_ip_ospf_common(vty, ospf, uj); + + return ret; } DEFUN (show_ip_ospf_instance, @@ -3556,7 +3587,8 @@ 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(VRF_DEFAULT), node, ifp)) { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), + node, ifp)) { if (ospf_oi_count(ifp)) { if (use_json) json_interface_sub = @@ -3575,7 +3607,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, } else { /* Interface name is specified. */ if ((ifp = if_lookup_by_name(argv[iface_argv]->arg, - VRF_DEFAULT)) + ospf->vrf_id)) == NULL) { if (use_json) json_object_boolean_true_add(json, @@ -3607,24 +3639,59 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_interface, show_ip_ospf_interface_cmd, - "show ip ospf interface [INTERFACE] [json]", + "show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Interface information\n" "Interface name\n" JSON_STR) { struct ospf *ospf; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (uj) argc--; - return show_ip_ospf_interface_common(vty, ospf, argc, argv, 4, uj); + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_interface_common(vty, + ospf, argc, + argv, 6, + uj); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = show_ip_ospf_interface_common(vty, ospf, + argc, argv, 6, uj); + + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = show_ip_ospf_interface_common(vty, ospf, + argc, argv, 4, uj); + } + + return ret; } DEFUN (show_ip_ospf_instance_interface, @@ -3795,8 +3862,6 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf, if (use_json) json = json_object_new_object(); - else - show_ip_ospf_neighbour_header(vty); if (ospf->instance) { if (use_json) @@ -3806,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); @@ -3821,20 +3888,54 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_neighbor, show_ip_ospf_neighbor_cmd, - "show ip ospf neighbor [json]", + "show ip ospf [vrf <NAME|all>] neighbor [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Neighbor list\n" JSON_STR) { struct ospf *ospf; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return show_ip_ospf_neighbor_common(vty, ospf, uj); + if (!uj) + show_ip_ospf_neighbour_header(vty); + + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_neighbor_common(vty, ospf, + uj); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } + + if (ospf) + ret = show_ip_ospf_neighbor_common(vty, ospf, uj); + + return ret; } @@ -3861,6 +3962,9 @@ DEFUN (show_ip_ospf_instance_neighbor, if (!ospf->oi_running) return CMD_SUCCESS; + if (!uj) + show_ip_ospf_neighbour_header(vty); + return show_ip_ospf_neighbor_common(vty, ospf, uj); } @@ -3875,8 +3979,7 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, if (use_json) { json = json_object_new_object(); json_neighbor_sub = json_object_new_object(); - } else - show_ip_ospf_neighbour_header(vty); + } if (ospf->instance) { if (use_json) @@ -3886,6 +3989,22 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } + if (ospf->name) { + if (use_json) { + json_object_int_add(json, "vrfId", + (ospf->vrf_id == VRF_UNKNOWN) + ? -1 : ospf->vrf_id); + json_object_string_add(json, "vrfName", + (ospf->vrf_id == VRF_DEFAULT) + ? "Default" : ospf->name); + } else { + vty_out(vty, "\nOSPF vrf: %s\n\n", + ospf->vrf_id == VRF_DEFAULT + ? "Default" : ospf->name); + } + } + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { struct listnode *nbr_node; struct ospf_nbr_nbma *nbr_nbma; @@ -3944,21 +4063,56 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_neighbor_all, show_ip_ospf_neighbor_all_cmd, - "show ip ospf neighbor all [json]", + "show ip ospf [vrf <NAME|all>] neighbor all [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Neighbor list\n" "include down status neighbor\n" JSON_STR) { struct ospf *ospf; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return show_ip_ospf_neighbor_all_common(vty, ospf, uj); + if (!uj) + show_ip_ospf_neighbour_header(vty); + + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_neighbor_all_common(vty, + ospf, + uj); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } + + if (ospf) + ret = show_ip_ospf_neighbor_all_common(vty, ospf, uj); + + return ret; } DEFUN (show_ip_ospf_instance_neighbor_all, @@ -3999,8 +4153,6 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, if (use_json) json = json_object_new_object(); - else - show_ip_ospf_neighbour_header(vty); if (ospf->instance) { if (use_json) @@ -4010,7 +4162,10 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } - ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT); + 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) { if (use_json) json_object_boolean_true_add(json, "noSuchIface"); @@ -4051,11 +4206,24 @@ DEFUN (show_ip_ospf_neighbor_int, struct ospf *ospf; int idx_ifname = 4; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + int ret = CMD_SUCCESS; + struct interface *ifp = NULL; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if (!uj) + show_ip_ospf_neighbour_header(vty); - return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj); + ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg); + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + if (!ifp || ifp->vrf_id != ospf->vrf_id) + continue; + ret = show_ip_ospf_neighbor_int_common(vty, ospf, + idx_ifname, argv, uj); + } + + return ret; } DEFUN (show_ip_ospf_instance_neighbor_int, @@ -4075,6 +4243,9 @@ DEFUN (show_ip_ospf_instance_neighbor_int, u_short instance = 0; u_char uj = use_json(argc, argv); + if (!uj) + show_ip_ospf_neighbour_header(vty); + instance = strtoul(argv[idx_number]->arg, NULL, 10); ospf = ospf_lookup_instance(instance); if (ospf == NULL) @@ -4083,6 +4254,9 @@ DEFUN (show_ip_ospf_instance_neighbor_int, if (!ospf->oi_running) return CMD_SUCCESS; + if (!uj) + show_ip_ospf_neighbour_header(vty); + return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj); } @@ -4402,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) @@ -4441,13 +4617,17 @@ DEFUN (show_ip_ospf_neighbor_id, JSON_STR) { struct ospf *ospf; - int idx_router_id = 4; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + int ret = CMD_SUCCESS; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj); + } - return show_ip_ospf_neighbor_id_common(vty, ospf, idx_router_id, argv, uj); + return ret; } DEFUN (show_ip_ospf_instance_neighbor_id, @@ -4497,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; @@ -4526,21 +4708,53 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty, DEFUN (show_ip_ospf_neighbor_detail, show_ip_ospf_neighbor_detail_cmd, - "show ip ospf neighbor detail [json]", + "show ip ospf [vrf <NAME|all>] neighbor detail [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Neighbor list\n" "detail of all neighbors\n" JSON_STR) { struct ospf *ospf; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return show_ip_ospf_neighbor_detail_common(vty, ospf, uj); + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_neighbor_detail_common(vty, + ospf, + uj); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } + + if (ospf) + ret = show_ip_ospf_neighbor_detail_common(vty, ospf, uj); + + return ret; } DEFUN (show_ip_ospf_instance_neighbor_detail, @@ -4589,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; @@ -4628,10 +4844,12 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty, DEFUN (show_ip_ospf_neighbor_detail_all, show_ip_ospf_neighbor_detail_all_cmd, - "show ip ospf neighbor detail all [json]", + "show ip ospf [vrf <NAME|all>] neighbor detail all [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Neighbor list\n" "detail of all neighbors\n" "include down status neighbor\n" @@ -4639,11 +4857,41 @@ DEFUN (show_ip_ospf_neighbor_detail_all, { struct ospf *ospf; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj); + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_neighbor_detail_all_common(vty, + ospf, + uj); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } + + if (ospf) + ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj); + + return ret; } DEFUN (show_ip_ospf_instance_neighbor_detail_all, @@ -4697,7 +4945,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } - ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT); + ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg); if (!ifp) { if (!use_json) vty_out(vty, "No such interface.\n"); @@ -4746,13 +4994,18 @@ DEFUN (show_ip_ospf_neighbor_int_detail, JSON_STR) { struct ospf *ospf; - int idx_ifname = 4; u_char uj = use_json(argc, argv); + struct listnode *node = NULL; + int ret = CMD_SUCCESS; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0, + argv, uj); + } - return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname, argv, uj); + return ret; } DEFUN (show_ip_ospf_instance_neighbor_int_detail, @@ -5362,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)); @@ -5429,29 +5684,62 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_database_max, show_ip_ospf_database_max_cmd, - "show ip ospf database <max-age|self-originate>", + "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Database summary\n" "LSAs in MaxAge list\n" "Self-originated link states\n") { - struct ospf *ospf; + struct ospf *ospf = NULL; + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_database_common(vty, ospf, + idx_vrf ? 2 + : 0, argc, + argv); + } + } else { + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = (show_ip_ospf_database_common(vty, ospf, idx_vrf ? + 2 : 0, argc, argv)); + } + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv); + } - return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv)); + return ret; } DEFUN (show_ip_ospf_instance_database, show_ip_ospf_instance_database_cmd, - "show ip ospf [(1-65535)] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]", + "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]", SHOW_STR IP_STR "OSPF information\n" "Instance ID\n" + VRF_CMD_HELP_STR "Database summary\n" OSPF_LSA_TYPES_DESC "Link State ID (as an IP address)\n" @@ -5461,22 +5749,53 @@ DEFUN (show_ip_ospf_instance_database, { struct ospf *ospf; u_short instance = 0; - + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; int idx = 0; + if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); ospf = ospf_lookup_instance(instance); if (ospf == NULL) return CMD_NOT_MY_INSTANCE; - } else { - ospf = ospf_lookup(); + if (!ospf->oi_running) + return CMD_SUCCESS; + + return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, + argc, argv)); + } else if (argv_find(argv, argc, "vrf", &idx)) { + vrf_name = argv[++idx]->arg; + all_vrf = strmatch(vrf_name, "all"); } - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = (show_ip_ospf_database_common(vty, ospf, + idx ? 2 : 0, + argc, argv)); + } + } else { + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if ((ospf == NULL) || !ospf->oi_running) + return CMD_SUCCESS; + ret = (show_ip_ospf_database_common(vty, ospf, idx ? 2 : + 0, argc, argv)); + } + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv)); + } - return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc, - argv)); + return ret; } DEFUN (show_ip_ospf_instance_database_max, @@ -5519,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)); @@ -5560,34 +5881,69 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, DEFUN (show_ip_ospf_instance_database_type_adv_router, show_ip_ospf_instance_database_type_adv_router_cmd, - "show ip ospf [(1-65535)] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>", + "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>", SHOW_STR IP_STR "OSPF information\n" "Instance ID\n" + VRF_CMD_HELP_STR "Database summary\n" OSPF_LSA_TYPES_DESC "Advertising Router link states\n" "Advertising Router (as an IP address)\n" "Self-originated link states\n") { - struct ospf *ospf; + struct ospf *ospf = NULL; u_short instance = 0; - int idx = 0; + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx = 0, idx_vrf = 0; if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); ospf = ospf_lookup_instance(instance); if (ospf == NULL) return CMD_NOT_MY_INSTANCE; - } else - ospf = ospf_lookup(); + if (!ospf->oi_running) + return CMD_SUCCESS; + return (show_ip_ospf_database_type_adv_router_common(vty, ospf, + idx ? 1 : 0, + argc, + argv)); + } - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return (show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv)); + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_database_type_adv_router_common(vty, + ospf, idx ? 1 : 0, argc, argv); + } + } else { + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if ((ospf == NULL) || !ospf->oi_running) + return CMD_SUCCESS; + ret = show_ip_ospf_database_type_adv_router_common(vty, + ospf, idx ? 1 : 0, argc, argv); + } + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = show_ip_ospf_database_type_adv_router_common(vty, ospf, + idx ? 1 : 0, + argc, argv); + } + return ret; + /*return (show_ip_ospf_database_type_adv_router_common( + vty, ospf, idx ? 1 : 0, argc, argv));*/ } DEFUN (ip_ospf_authentication_args, @@ -5871,8 +6227,7 @@ DEFUN_HIDDEN (ospf_authentication_key, ospf_authentication_key_cmd, "ospf authentication-key AUTH_KEY [A.B.C.D]", "OSPF interface commands\n" - "Authentication password (key)\n" - "The OSPF password (key)\n" + VLINK_HELPSTR_AUTH_SIMPLE "Address of interface\n") { return ip_ospf_authentication_key(self, vty, argc, argv); @@ -5884,8 +6239,8 @@ DEFUN (no_ip_ospf_authentication_key, NO_STR "IP Information\n" "OSPF interface commands\n" - "Authentication password (key)\n" - "The OSPF password (key)") + VLINK_HELPSTR_AUTH_SIMPLE + "Address of interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); int idx = 0; @@ -5921,8 +6276,8 @@ DEFUN_HIDDEN (no_ospf_authentication_key, "no ospf authentication-key [AUTH_KEY [A.B.C.D]]", NO_STR "OSPF interface commands\n" - "Authentication password (key)\n" - "The OSPF password (key)") + VLINK_HELPSTR_AUTH_SIMPLE + "Address of interface\n") { return no_ip_ospf_authentication_key(self, vty, argc, argv); } @@ -6068,19 +6423,19 @@ DEFUN (ip_ospf_cost, { VTY_DECLVAR_CONTEXT(interface, ifp); int idx = 0; - u_int32_t cost; + u_int32_t cost = OSPF_OUTPUT_COST_DEFAULT; struct in_addr addr; struct ospf_if_params *params; params = IF_DEF_PARAMS(ifp); // get arguments char *coststr = NULL, *ifaddr = NULL; - coststr = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg - : NULL; - ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; + argv_find(argv, argc, "(1-65535)", &idx); + coststr = argv[idx]->arg; cost = strtol(coststr, NULL, 10); + ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; if (ifaddr) { if (!inet_aton(ifaddr, &addr)) { vty_out(vty, @@ -6234,8 +6589,10 @@ static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str, /* Update timer values in neighbor structure. */ if (nbr_str) { - struct ospf *ospf; - if ((ospf = ospf_lookup())) { + struct ospf *ospf = NULL; + + ospf = ospf_lookup_by_vrf_id(ifp->vrf_id); + if (ospf) { oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr); if (oi) ospf_nbr_timer_update(oi); @@ -6346,9 +6703,10 @@ DEFUN (no_ip_ospf_dead_interval, /* Update timer values in neighbor structure. */ if (argc == 1) { - struct ospf *ospf; + struct ospf *ospf = NULL; - if ((ospf = ospf_lookup())) { + ospf = ospf_lookup_by_vrf_id(ifp->vrf_id); + if (ospf) { oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr); if (oi) ospf_nbr_timer_update(oi); @@ -6930,9 +7288,9 @@ DEFUN (ip_ospf_area, int format, ret; struct in_addr area_id; struct in_addr addr; - struct ospf_if_params *params; + struct ospf_if_params *params = NULL; struct route_node *rn; - struct ospf *ospf; + struct ospf *ospf = NULL; u_short instance = 0; char *areaid; @@ -6942,13 +7300,17 @@ DEFUN (ip_ospf_area, argv_find(argv, argc, "area", &idx); areaid = argv[idx + 1]->arg; - ospf = ospf_lookup_instance(instance); + if (ifp->vrf_id && !instance) + ospf = ospf_lookup_by_vrf_id(ifp->vrf_id); + else + ospf = ospf_lookup_instance(instance); + if (ospf == NULL) { params = IF_DEF_PARAMS(ifp); if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { UNSET_IF_PARAM(params, if_area); - ospf_interface_area_unset(ifp); - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + ospf_interface_area_unset(ospf, ifp); ospf->if_ospf_cli_count--; } return CMD_NOT_MY_INSTANCE; @@ -6997,10 +7359,12 @@ DEFUN (ip_ospf_area, } /* enable ospf on this interface with area_id */ - SET_IF_PARAM(params, if_area); - params->if_area = area_id; - params->if_area_id_fmt = format; - ospf_interface_area_set(ifp); + if (params) { + SET_IF_PARAM(params, if_area); + params->if_area = area_id; + params->if_area_id_fmt = format; + } + ospf_interface_area_set(ospf, ifp); ospf->if_ospf_cli_count++; return CMD_SUCCESS; @@ -7028,7 +7392,11 @@ DEFUN (no_ip_ospf_area, if (argv_find(argv, argc, "(1-65535)", &idx)) instance = strtol(argv[idx]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); + if (ifp->vrf_id && !instance) + ospf = ospf_lookup_by_vrf_id(ifp->vrf_id); + else + ospf = ospf_lookup_instance(instance); + if (ospf == NULL) return CMD_NOT_MY_INSTANCE; @@ -7058,7 +7426,7 @@ DEFUN (no_ip_ospf_area, ospf_if_update_params((ifp), (addr)); } - ospf_interface_area_unset(ifp); + ospf_interface_area_unset(ospf, ifp); ospf->if_ospf_cli_count--; return CMD_SUCCESS; } @@ -7732,7 +8100,7 @@ DEFUN (ospf_max_metric_router_lsa_startup, int idx_number = 3; unsigned int seconds; - if (argc != 1) { + if (argc < 4) { vty_out(vty, "%% Must supply stub-router period"); return CMD_WARNING_CONFIG_FAILED; } @@ -7788,7 +8156,7 @@ DEFUN (ospf_max_metric_router_lsa_shutdown, int idx_number = 3; unsigned int seconds; - if (argc != 1) { + if (argc < 4) { vty_out(vty, "%% Must supply stub-router shutdown period"); return CMD_WARNING_CONFIG_FAILED; } @@ -7837,7 +8205,8 @@ static void config_write_stub_router(struct vty *vty, struct ospf *ospf) return; } -static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt) +static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, + struct route_table *rt) { struct route_node *rn; struct ospf_route * or ; @@ -7877,14 +8246,14 @@ static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt) for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode, path)) { if (if_lookup_by_index(path->ifindex, - VRF_DEFAULT)) { + ospf->vrf_id)) { if (path->nexthop.s_addr == 0) vty_out(vty, "%24s directly attached to %s\n", "", ifindex2ifname( path->ifindex, - VRF_DEFAULT)); + ospf->vrf_id)); else vty_out(vty, "%24s via %s, %s\n", @@ -7893,14 +8262,15 @@ static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt) path->nexthop), ifindex2ifname( path->ifindex, - VRF_DEFAULT)); + ospf->vrf_id)); } } } vty_out(vty, "\n"); } -static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs) +static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, + struct route_table *rtrs) { struct route_node *rn; struct ospf_route * or ; @@ -7939,14 +8309,14 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs) for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) { if (if_lookup_by_index(path->ifindex, - VRF_DEFAULT)) { + ospf->vrf_id)) { if (path->nexthop.s_addr == 0) vty_out(vty, "%24s directly attached to %s\n", "", ifindex2ifname( path->ifindex, - VRF_DEFAULT)); + ospf->vrf_id)); else vty_out(vty, "%24s via %s, %s\n", @@ -7955,7 +8325,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs) path->nexthop), ifindex2ifname( path->ifindex, - VRF_DEFAULT)); + ospf->vrf_id)); } } } @@ -7963,7 +8333,8 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs) vty_out(vty, "\n"); } -static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt) +static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, + struct route_table *rt) { struct route_node *rn; struct ospf_route *er; @@ -7996,14 +8367,14 @@ static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt) for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode, path)) { if (if_lookup_by_index(path->ifindex, - VRF_DEFAULT)) { + ospf->vrf_id)) { if (path->nexthop.s_addr == 0) vty_out(vty, "%24s directly attached to %s\n", "", ifindex2ifname( path->ifindex, - VRF_DEFAULT)); + ospf->vrf_id)); else vty_out(vty, "%24s via %s, %s\n", @@ -8012,7 +8383,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt) path->nexthop), ifindex2ifname( path->ifindex, - VRF_DEFAULT)); + ospf->vrf_id)); } } } @@ -8025,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; @@ -8034,7 +8407,7 @@ static int show_ip_ospf_border_routers_common(struct vty *vty, show_ip_ospf_route_network (vty, ospf->new_table); */ /* Show Router routes. */ - show_ip_ospf_route_router(vty, ospf->new_rtrs); + show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs); vty_out(vty, "\n"); @@ -8043,18 +8416,49 @@ static int show_ip_ospf_border_routers_common(struct vty *vty, DEFUN (show_ip_ospf_border_routers, show_ip_ospf_border_routers_cmd, - "show ip ospf border-routers", + "show ip ospf [vrf <NAME|all>] border-routers", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" "Show all the ABR's and ASBR's\n") { - struct ospf *ospf; + struct ospf *ospf = NULL; + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return show_ip_ospf_border_routers_common(vty, ospf); + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + + ret = show_ip_ospf_border_routers_common(vty, + ospf); + } + } else { + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + + ret = show_ip_ospf_border_routers_common(vty, ospf); + } + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + ret = show_ip_ospf_border_routers_common(vty, ospf); + } + + return ret; } DEFUN (show_ip_ospf_instance_border_routers, @@ -8086,19 +8490,21 @@ 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; } /* Show Network routes. */ - show_ip_ospf_route_network(vty, ospf->new_table); + show_ip_ospf_route_network(vty, ospf, ospf->new_table); /* Show Router routes. */ - show_ip_ospf_route_router(vty, ospf->new_rtrs); + show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs); /* Show AS External routes. */ - show_ip_ospf_route_external(vty, ospf->old_external_route); + show_ip_ospf_route_external(vty, ospf, ospf->old_external_route); vty_out(vty, "\n"); @@ -8107,18 +8513,48 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf) DEFUN (show_ip_ospf_route, show_ip_ospf_route_cmd, - "show ip ospf route", - SHOW_STR - IP_STR - "OSPF information\n" - "OSPF routing table\n") -{ - struct ospf *ospf; + "show ip ospf [vrf <NAME|all>] route", + SHOW_STR + IP_STR + "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" + "OSPF routing table\n") +{ + struct ospf *ospf = NULL; + struct listnode *node = NULL; + char *vrf_name = NULL; + bool all_vrf = FALSE; + int ret = CMD_SUCCESS; + int inst = 0; + int idx_vrf = 0; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - return show_ip_ospf_route_common(vty, ospf); + /* vrf input is provided could be all or specific vrf*/ + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = show_ip_ospf_route_common(vty, ospf); + } + return ret; + } + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } else { + /* Display default ospf (instance 0) info */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) + return CMD_SUCCESS; + } + + if (ospf) + ret = show_ip_ospf_route_common(vty, ospf); + + return ret; } DEFUN (show_ip_ospf_instance_route, @@ -8145,6 +8581,77 @@ DEFUN (show_ip_ospf_instance_route, return show_ip_ospf_route_common(vty, ospf); } + +DEFUN (show_ip_ospf_vrfs, + show_ip_ospf_vrfs_cmd, + "show ip ospf vrfs [json]", + SHOW_STR + IP_STR + "OSPF information\n" + "Show OSPF VRFs \n" + JSON_STR) +{ + u_char uj = use_json(argc, argv); + json_object *json = NULL; + json_object *json_vrfs = NULL; + struct ospf *ospf = NULL; + struct listnode *node = NULL; + int count = 0; + static char header[] = "Name Id RouterId "; + + if (uj) { + json = json_object_new_object(); + json_vrfs = json_object_new_object(); + } + + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + json_object *json_vrf = NULL; + const char *name = NULL; + int vrf_id_ui = 0; + + count++; + + if (!uj && count == 1) + vty_out(vty, "%s\n", header); + if (uj) + json_vrf = json_object_new_object(); + + if (ospf->vrf_id == 0) + name = VRF_DEFAULT_NAME; + else + name = ospf->name; + + vrf_id_ui = (ospf->vrf_id == VRF_UNKNOWN) ? -1 : ospf->vrf_id; + + if (uj) { + json_object_int_add(json_vrf, "vrfId", vrf_id_ui); + json_object_string_add(json_vrf, "routerId", + inet_ntoa(ospf->router_id)); + + json_object_object_add(json_vrfs, name, json_vrf); + + } else { + vty_out(vty, "%-25s %-5d %-16s \n", + name, ospf->vrf_id, inet_ntoa(ospf->router_id)); + } + } + + if (uj) { + json_object_object_add(json, "vrfs", json_vrfs); + json_object_int_add(json, "totalVrfs", count); + + vty_out(vty, "%s\n", json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else { + if (count) + vty_out(vty, "\nTotal number of OSPF VRFs (including default): %d\n", + count); + } + + return CMD_SUCCESS; +} + const char *ospf_abr_type_str[] = {"unknown", "standard", "ibm", "cisco", "shortcut"}; @@ -8156,26 +8663,32 @@ const char *ospf_int_type_str[] = {"unknown", /* should never be used. */ "virtual-link", /* should never be used. */ "loopback"}; -/* Configuration write function for ospfd. */ -static int config_write_interface(struct vty *vty) +static int config_write_interface_one(struct vty *vty, struct ospf *ospf) { struct listnode *n1, *n2; struct interface *ifp; struct crypt_key *ck; - int write = 0; struct route_node *rn = NULL; struct ospf_if_params *params; - struct ospf *ospf = ospf_lookup(); + int write = 0; + + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) { + struct vrf *vrf = NULL; - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), n1, ifp)) { 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"); - vty_frame(vty, "interface %s\n", ifp->name); + if (ifp->vrf_id == VRF_DEFAULT || vrf == NULL) + vty_frame(vty, "interface %s\n", ifp->name); + else + vty_frame(vty, "interface %s vrf %s\n", + ifp->name, vrf->name); if (ifp->desc) vty_out(vty, " description %s\n", ifp->desc); @@ -8190,11 +8703,11 @@ static int config_write_interface(struct vty *vty) if (params->type != ospf_default_iftype(ifp)) { vty_out(vty, " ip ospf network %s", ospf_int_type_str - [params->type]); + [params->type]); if (params != IF_DEF_PARAMS(ifp)) vty_out(vty, " %s", inet_ntoa( - rn->p.u.prefix4)); + rn->p.u.prefix4)); vty_out(vty, "\n"); } } @@ -8205,8 +8718,8 @@ static int config_write_interface(struct vty *vty) const char *auth_str; /* Translation tables are not that much help - here due to syntax - of the simple option */ + * here due to syntax + * of the simple option */ switch (params->auth_type) { case OSPF_AUTH_NULL: @@ -8246,18 +8759,22 @@ static int config_write_interface(struct vty *vty) } /* Cryptographic Authentication Key print. */ - for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, n2, ck)) { - vty_out(vty, - " ip ospf message-digest-key %d md5 %s", - ck->key_id, ck->auth_key); - if (params != IF_DEF_PARAMS(ifp)) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); - vty_out(vty, "\n"); + if (params && params->auth_crypt) { + for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, + n2, ck)) { + vty_out(vty, + " ip ospf message-digest-key %d md5 %s", + ck->key_id, ck->auth_key); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } } /* Interface Output Cost print. */ - if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) { + if (OSPF_IF_PARAM_CONFIGURED(params, + output_cost_cmd)) { vty_out(vty, " ip ospf cost %u", params->output_cost_cmd); if (params != IF_DEF_PARAMS(ifp)) @@ -8281,7 +8798,7 @@ static int config_write_interface(struct vty *vty) /* Router Dead Interval print. */ if (OSPF_IF_PARAM_CONFIGURED(params, v_wait) && params->v_wait - != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) { + != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) { vty_out(vty, " ip ospf dead-interval "); /* fast hello ? */ @@ -8302,7 +8819,7 @@ static int config_write_interface(struct vty *vty) /* Router Priority print. */ if (OSPF_IF_PARAM_CONFIGURED(params, priority) && params->priority - != OSPF_ROUTER_PRIORITY_DEFAULT) { + != OSPF_ROUTER_PRIORITY_DEFAULT) { vty_out(vty, " ip ospf priority %u", params->priority); if (params != IF_DEF_PARAMS(ifp)) @@ -8315,7 +8832,7 @@ static int config_write_interface(struct vty *vty) if (OSPF_IF_PARAM_CONFIGURED(params, retransmit_interval) && params->retransmit_interval - != OSPF_RETRANSMIT_INTERVAL_DEFAULT) { + != OSPF_RETRANSMIT_INTERVAL_DEFAULT) { vty_out(vty, " ip ospf retransmit-interval %u", params->retransmit_interval); if (params != IF_DEF_PARAMS(ifp)) @@ -8327,7 +8844,7 @@ static int config_write_interface(struct vty *vty) /* Transmit Delay print. */ if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay) && params->transmit_delay - != OSPF_TRANSMIT_DELAY_DEFAULT) { + != OSPF_TRANSMIT_DELAY_DEFAULT) { vty_out(vty, " ip ospf transmit-delay %u", params->transmit_delay); if (params != IF_DEF_PARAMS(ifp)) @@ -8348,7 +8865,9 @@ static int config_write_interface(struct vty *vty) size_t buflen = MAX(strlen("4294967295"), strlen("255.255.255.255")); char buf[buflen]; - area_id2str(buf, sizeof(buf), ¶ms->if_area, + + area_id2str(buf, sizeof(buf), + ¶ms->if_area, params->if_area_id_fmt); vty_out(vty, " area %s", buf); if (params != IF_DEF_PARAMS(ifp)) @@ -8392,6 +8911,19 @@ static int config_write_interface(struct vty *vty) vty_endframe(vty, NULL); } + return write; +} + +/* Configuration write function for ospfd. */ +static int config_write_interface(struct vty *vty) +{ + int write = 0; + struct ospf *ospf = NULL; + struct listnode *node = NULL; + + /* Traverse all ospf [vrf] instances */ + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) + write += config_write_interface_one(vty, ospf); return write; } @@ -8732,154 +9264,174 @@ static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf) return 0; } -/* OSPF configuration write function. */ -static int ospf_config_write(struct vty *vty) +static int ospf_config_write_one(struct vty *vty, struct ospf *ospf) { - struct ospf *ospf; struct interface *ifp; struct ospf_interface *oi; - struct listnode *node; + struct listnode *node = NULL; int write = 0; - ospf = ospf_lookup(); - if (ospf != NULL && ospf->oi_running) { - /* `router ospf' print. */ - if (ospf->instance) - vty_out(vty, "router ospf %d\n", ospf->instance); - else - vty_out(vty, "router ospf\n"); + /* `router ospf' print. */ + if (ospf->instance && ospf->name) { + vty_out(vty, "router ospf %d vrf %s\n", + ospf->instance, ospf->name); + } else if (ospf->instance) { + vty_out(vty, "router ospf %d\n", + ospf->instance); + } else if (ospf->name) { + vty_out(vty, "router ospf vrf %s\n", + ospf->name); + } else + vty_out(vty, "router ospf\n"); + if (!ospf->networks) { write++; + return write; + } - if (!ospf->networks) - return write; - - /* Router ID print. */ - if (ospf->router_id_static.s_addr != 0) - vty_out(vty, " ospf router-id %s\n", - inet_ntoa(ospf->router_id_static)); - - /* ABR type print. */ - if (ospf->abr_type != OSPF_ABR_DEFAULT) - vty_out(vty, " ospf abr-type %s\n", - ospf_abr_type_str[ospf->abr_type]); - - /* log-adjacency-changes flag print. */ - if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) { - if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) - vty_out(vty, " log-adjacency-changes detail\n"); - else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES) - vty_out(vty, " log-adjacency-changes\n"); - } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) { - vty_out(vty, " no log-adjacency-changes\n"); - } + /* Router ID print. */ + if (ospf->router_id_static.s_addr != 0) + vty_out(vty, " ospf router-id %s\n", + inet_ntoa(ospf->router_id_static)); - /* RFC1583 compatibility flag print -- Compatible with CISCO - * 12.1. */ - if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) - vty_out(vty, " compatible rfc1583\n"); + /* ABR type print. */ + if (ospf->abr_type != OSPF_ABR_DEFAULT) + vty_out(vty, " ospf abr-type %s\n", + ospf_abr_type_str[ospf->abr_type]); - /* auto-cost reference-bandwidth configuration. */ - if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) { - vty_out(vty, - "! Important: ensure reference bandwidth " - "is consistent across all routers\n"); - vty_out(vty, " auto-cost reference-bandwidth %d\n", - ospf->ref_bandwidth); - } + /* log-adjacency-changes flag print. */ + if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) + vty_out(vty, " log-adjacency-changes detail\n"); + else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES) + vty_out(vty, " log-adjacency-changes\n"); + } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) { + vty_out(vty, " no log-adjacency-changes\n"); + } - /* SPF timers print. */ - if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT - || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT - || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT) - vty_out(vty, " timers throttle spf %d %d %d\n", - ospf->spf_delay, ospf->spf_holdtime, - ospf->spf_max_holdtime); - - /* LSA timers print. */ - if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL) - vty_out(vty, " timers throttle lsa all %d\n", - ospf->min_ls_interval); - if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL) - vty_out(vty, " timers lsa min-arrival %d\n", - ospf->min_ls_arrival); - - /* Write multiplier print. */ - if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT) - vty_out(vty, " ospf write-multiplier %d\n", - ospf->write_oi_count); - - /* Max-metric router-lsa print */ - config_write_stub_router(vty, ospf); - - /* SPF refresh parameters print. */ - if (ospf->lsa_refresh_interval - != OSPF_LSA_REFRESH_INTERVAL_DEFAULT) - vty_out(vty, " refresh timer %d\n", - ospf->lsa_refresh_interval); - - /* Redistribute information print. */ - config_write_ospf_redistribute(vty, ospf); - - /* passive-interface print. */ - if (ospf->passive_interface_default == OSPF_IF_PASSIVE) - vty_out(vty, " passive-interface default\n"); - - for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) - if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), - passive_interface) - && IF_DEF_PARAMS(ifp)->passive_interface - != ospf->passive_interface_default) { - vty_out(vty, " %spassive-interface %s\n", - IF_DEF_PARAMS(ifp)->passive_interface - ? "" - : "no ", - ifp->name); - } - for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { - if (!OSPF_IF_PARAM_CONFIGURED(oi->params, - passive_interface)) - continue; - if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp), - passive_interface)) { - if (oi->params->passive_interface - == IF_DEF_PARAMS(oi->ifp) - ->passive_interface) - continue; - } else if (oi->params->passive_interface - == ospf->passive_interface_default) - continue; + /* RFC1583 compatibility flag print -- Compatible with CISCO + * 12.1. */ + if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) + vty_out(vty, " compatible rfc1583\n"); - vty_out(vty, " %spassive-interface %s %s\n", - oi->params->passive_interface ? "" : "no ", - oi->ifp->name, - inet_ntoa(oi->address->u.prefix4)); - } + /* auto-cost reference-bandwidth configuration. */ + if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) { + vty_out(vty, + "! Important: ensure reference bandwidth " + "is consistent across all routers\n"); + vty_out(vty, " auto-cost reference-bandwidth %d\n", + ospf->ref_bandwidth); + } - /* Network area print. */ - config_write_network_area(vty, ospf); + /* SPF timers print. */ + if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT + || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT + || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT) + vty_out(vty, " timers throttle spf %d %d %d\n", + ospf->spf_delay, ospf->spf_holdtime, + ospf->spf_max_holdtime); - /* Area config print. */ - config_write_ospf_area(vty, ospf); + /* LSA timers print. */ + if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL) + vty_out(vty, " timers throttle lsa all %d\n", + ospf->min_ls_interval); + if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL) + vty_out(vty, " timers lsa min-arrival %d\n", + ospf->min_ls_arrival); - /* static neighbor print. */ - config_write_ospf_nbr_nbma(vty, ospf); + /* Write multiplier print. */ + if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT) + vty_out(vty, " ospf write-multiplier %d\n", + ospf->write_oi_count); - /* Virtual-Link print. */ - config_write_virtual_link(vty, ospf); + /* Max-metric router-lsa print */ + config_write_stub_router(vty, ospf); - /* Default metric configuration. */ - config_write_ospf_default_metric(vty, ospf); + /* SPF refresh parameters print. */ + if (ospf->lsa_refresh_interval + != OSPF_LSA_REFRESH_INTERVAL_DEFAULT) + vty_out(vty, " refresh timer %d\n", + ospf->lsa_refresh_interval); - /* Distribute-list and default-information print. */ - config_write_ospf_distribute(vty, ospf); + /* Redistribute information print. */ + config_write_ospf_redistribute(vty, ospf); - /* Distance configuration. */ - config_write_ospf_distance(vty, ospf); + /* passive-interface print. */ + 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)) + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), + passive_interface) + && IF_DEF_PARAMS(ifp)->passive_interface + != ospf->passive_interface_default) { + vty_out(vty, " %spassive-interface %s\n", + IF_DEF_PARAMS(ifp)->passive_interface + ? "" + : "no ", + ifp->name); + } + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + if (!OSPF_IF_PARAM_CONFIGURED(oi->params, + passive_interface)) + continue; + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp), + passive_interface)) { + if (oi->params->passive_interface + == IF_DEF_PARAMS(oi->ifp) + ->passive_interface) + continue; + } else if (oi->params->passive_interface + == ospf->passive_interface_default) + continue; - ospf_opaque_config_write_router(vty, ospf); + vty_out(vty, " %spassive-interface %s %s\n", + oi->params->passive_interface ? "" : "no ", + oi->ifp->name, + inet_ntoa(oi->address->u.prefix4)); } + /* Network area print. */ + config_write_network_area(vty, ospf); + + /* Area config print. */ + config_write_ospf_area(vty, ospf); + + /* static neighbor print. */ + config_write_ospf_nbr_nbma(vty, ospf); + + /* Virtual-Link print. */ + config_write_virtual_link(vty, ospf); + + /* Default metric configuration. */ + config_write_ospf_default_metric(vty, ospf); + + /* Distribute-list and default-information print. */ + config_write_ospf_distribute(vty, ospf); + + /* Distance configuration. */ + config_write_ospf_distance(vty, ospf); + + ospf_opaque_config_write_router(vty, ospf); + + write++; + return write; +} + +/* OSPF configuration write function. */ +static int ospf_config_write(struct vty *vty) +{ + struct ospf *ospf; + struct listnode *ospf_node = NULL; + int write = 0; + + if (listcount(om->ospf) == 0) + return write; + + for (ALL_LIST_ELEMENTS_RO(om->ospf, ospf_node, ospf)) { + if (ospf->oi_running) + write += ospf_config_write_one(vty, ospf); + } return write; } @@ -8928,6 +9480,9 @@ void ospf_vty_show_init(void) install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd); install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd); + + /* "show ip ospf vrfs" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd); } @@ -9068,17 +9623,20 @@ DEFUN (clear_ip_ospf_interface, { int idx_ifname = 4; struct interface *ifp; - struct listnode *node; + struct listnode *node, *n1; + struct ospf *ospf = NULL; if (argc == 4) /* Clear all the ospfv2 interfaces. */ { - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) - ospf_interface_clear(ifp); - } else /* Interface name is specified. */ - { - if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg, - VRF_DEFAULT)) - == NULL) + for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), + node, ifp)) + ospf_interface_clear(ifp); + } + } else { + /* Interface name is specified. */ + ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg); + if (ifp == NULL) vty_out(vty, "No such interface name\n"); else ospf_interface_clear(ifp); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 9bba2c9806..16f87735be 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -53,6 +53,7 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table") DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute") +DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments") DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) @@ -68,23 +69,33 @@ struct in_addr router_id_zebra; static int ospf_router_id_update_zebra(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { - struct ospf *ospf; + struct ospf *ospf = NULL; struct prefix router_id; zebra_router_id_update_read(zclient->ibuf, &router_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { char buf[PREFIX2STR_BUFFER]; prefix2str(&router_id, buf, sizeof(buf)); - zlog_debug("Zebra rcvd: router id update %s", buf); + zlog_debug("Zebra rcvd: router id update %s vrf %s id %u", + buf, ospf_vrf_id_to_name(vrf_id), vrf_id); } router_id_zebra = router_id.u.prefix4; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(vrf_id); if (ospf != NULL) ospf_router_id_update(ospf); - + else { + if (IS_DEBUG_OSPF_EVENT) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str(&router_id, buf, sizeof(buf)); + zlog_debug("%s: ospf instance not found for vrf %s id %u router_id %s", + __PRETTY_FUNCTION__, + ospf_vrf_id_to_name(vrf_id), vrf_id, buf); + } + } return 0; } @@ -92,14 +103,18 @@ static int ospf_router_id_update_zebra(int command, struct zclient *zclient, static int ospf_interface_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; + struct interface *ifp = NULL; + struct ospf *ospf = NULL; ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); + if (ifp == NULL) + return 0; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) zlog_debug( - "Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d", - ifp->name, ifp->vrf_id, ifp->ifindex, + "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d", + ifp->name, ospf_vrf_id_to_name(ifp->vrf_id), + ifp->vrf_id, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); assert(ifp->info); @@ -109,7 +124,11 @@ static int ospf_interface_add(int command, struct zclient *zclient, IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); } - ospf_if_update(NULL, ifp); + ospf = ospf_lookup_by_vrf_id(vrf_id); + if (!ospf) + return 0; + + ospf_if_update(ospf, ifp); hook_call(ospf_if_update, ifp); @@ -136,8 +155,9 @@ static int ospf_interface_delete(int command, struct zclient *zclient, if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) zlog_debug( - "Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d", - ifp->name, ifp->vrf_id, ifp->ifindex, + "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d", + ifp->name, ospf_vrf_id_to_name(ifp->vrf_id), + ifp->vrf_id, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); hook_call(ospf_if_delete, ifp); @@ -160,7 +180,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s, /* And look it up. */ return if_lookup_by_name_len( - ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT); + ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id); } static int ospf_interface_state_up(int command, struct zclient *zclient, @@ -249,6 +269,8 @@ static int ospf_interface_address_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; + struct ospf *ospf = NULL; + c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); @@ -258,11 +280,16 @@ static int ospf_interface_address_add(int command, struct zclient *zclient, if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { char buf[PREFIX2STR_BUFFER]; prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address add %s", c->ifp->name, - buf); + zlog_debug("Zebra: interface %s address add %s vrf %s id %u", + c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id), + vrf_id); } - ospf_if_update(NULL, c->ifp); + ospf = ospf_lookup_by_vrf_id(vrf_id); + if (!ospf) + return 0; + + ospf_if_update(ospf, c->ifp); hook_call(ospf_if_update, c->ifp); @@ -330,19 +357,41 @@ static int ospf_interface_link_params(int command, struct zclient *zclient, return 0; } +/* VRF update for an interface. */ +static int ospf_interface_vrf_update(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) +{ + struct interface *ifp = NULL; + vrf_id_t new_vrf_id; + + ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, + &new_vrf_id); + if (!ifp) + return 0; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u", + __PRETTY_FUNCTION__, ifp->name, vrf_id, + ospf_vrf_id_to_name(new_vrf_id), new_vrf_id); + + /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/ + if_update_to_new_vrf(ifp, new_vrf_id); + + return 0; +} -void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) +void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route *or) { struct zapi_route api; struct zapi_nexthop *api_nh; u_char distance; struct ospf_path *path; struct listnode *node; - struct ospf *ospf = ospf_lookup(); int count = 0; memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -368,7 +417,7 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) } /* Distance value. */ - distance = ospf_distance_apply(p, or); + distance = ospf_distance_apply(ospf, p, or); if (distance) { SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; @@ -413,13 +462,13 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } -void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) +void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route *or) { struct zapi_route api; - struct ospf *ospf = ospf_lookup(); memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -435,13 +484,12 @@ void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } -void ospf_zebra_add_discard(struct prefix_ipv4 *p) +void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) { struct zapi_route api; - struct ospf *ospf = ospf_lookup(); memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -455,13 +503,12 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p) inet_ntoa(p->prefix), p->prefixlen); } -void ospf_zebra_delete_discard(struct prefix_ipv4 *p) +void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) { struct zapi_route api; - struct ospf *ospf = ospf_lookup(); memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -527,8 +574,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); } @@ -586,8 +632,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); @@ -595,11 +640,11 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance) } -int ospf_is_type_redistributed(int type, u_short instance) +int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance) { return (DEFAULT_ROUTE_TYPE(type) ? vrf_bitmap_check(zclient->default_information, - VRF_DEFAULT) + ospf->vrf_id) : ((instance && redist_check_instance( &zclient->mi_redist[AFI_IP][type], @@ -607,7 +652,7 @@ int ospf_is_type_redistributed(int type, u_short instance) || (!instance && vrf_bitmap_check( zclient->redist[AFI_IP][type], - VRF_DEFAULT)))); + ospf->vrf_id)))); } int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance, @@ -617,7 +662,7 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance, struct ospf_redist *red; red = ospf_redist_lookup(ospf, type, instance); - if (ospf_is_type_redistributed(type, instance)) { + if (ospf_is_type_redistributed(ospf, type, instance)) { if (mtype != red->dmetric.type) { red->dmetric.type = mtype; force = LSA_REFRESH_FORCE; @@ -645,11 +690,11 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance, ospf_external_add(type, instance); zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, - instance, VRF_DEFAULT); + instance, ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Redistribute[%s][%d]: Start Type[%d], Metric[%d]", - ospf_redist_string(type), instance, + zlog_debug("Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]", + ospf_redist_string(type), instance, ospf->vrf_id, metric_type(ospf, type, instance), metric_value(ospf, type, instance)); @@ -663,15 +708,15 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance) if (type == zclient->redist_default && instance == zclient->instance) return CMD_SUCCESS; - if (!ospf_is_type_redistributed(type, instance)) + if (!ospf_is_type_redistributed(ospf, type, instance)) return CMD_SUCCESS; zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, - instance, VRF_DEFAULT); + instance, ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Redistribute[%s][%d]: Stop", - ospf_redist_string(type), instance); + zlog_debug("Redistribute[%s][%d] vrf id %u: Stop", + ospf_redist_string(type), instance, ospf->vrf_id); ospf_redist_del(ospf, type, instance); @@ -698,7 +743,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, ospf_external_add(DEFAULT_ROUTE, 0); - if (ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) { + if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) { /* if ospf->default_originate changes value, is calling ospf_external_lsa_refresh_default sufficient to implement the change? */ @@ -714,7 +759,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, } zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, - VRF_DEFAULT); + ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]", @@ -734,14 +779,14 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, int ospf_redistribute_default_unset(struct ospf *ospf) { - if (!ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) + if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) return CMD_SUCCESS; ospf->default_originate = DEFAULT_ORIGINATE_NONE; ospf_redist_del(ospf, DEFAULT_ROUTE, 0); zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, - VRF_DEFAULT); + ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Redistribute[DEFAULT]: Stop"); @@ -886,7 +931,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient, struct ospf *ospf; int i; - ospf = ospf_lookup(); + ospf = ospf_lookup_by_vrf_id(vrf_id); if (ospf == NULL) return 0; @@ -1019,10 +1064,13 @@ static int ospf_distribute_list_update_timer(struct thread *thread) struct external_info *ei; struct route_table *rt; struct ospf_lsa *lsa; - int type, default_refresh = 0; - struct ospf *ospf; + int type, default_refresh = 0, arg_type; + struct ospf *ospf = NULL; + void **arg = THREAD_ARG (thread); + + ospf = (struct ospf *)arg[0]; + arg_type = (int)(intptr_t)arg[1]; - ospf = ospf_lookup(); if (ospf == NULL) return 0; @@ -1030,6 +1078,12 @@ static int ospf_distribute_list_update_timer(struct thread *thread) zlog_info("Zebra[Redistribute]: distribute-list update timer fired!"); + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d", + __PRETTY_FUNCTION__, arg_type, + ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id); + } + /* foreach all external info. */ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { struct list *ext_list; @@ -1062,29 +1116,39 @@ static int ospf_distribute_list_update_timer(struct thread *thread) } if (default_refresh) ospf_external_lsa_refresh_default(ospf); + + XFREE(MTYPE_OSPF_DIST_ARGS, arg); return 0; } /* Update distribute-list and set timer to apply access-list. */ -void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type, +void ospf_distribute_list_update(struct ospf *ospf, int type, u_short instance) { struct route_table *rt; struct ospf_external *ext; + void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2); + + args[0] = ospf; + args[1] = (void *)((ptrdiff_t) 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; thread_add_timer_msec(master, ospf_distribute_list_update_timer, - (void *)type, ospf->min_ls_interval, + (void **)args, ospf->min_ls_interval, &ospf->t_distribute_update); } @@ -1095,134 +1159,148 @@ static void ospf_filter_update(struct access_list *access) int type; int abr_inv = 0; struct ospf_area *area; - struct listnode *node; + struct listnode *node, *n1; /* If OSPF instance does not exist, return right now. */ - ospf = ospf_lookup(); - if (ospf == NULL) + if (listcount(om->ospf) == 0) return; - /* Update distribute-list, and apply filter. */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (red_list) - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { - if (ROUTEMAP(red)) { - /* if route-map is not NULL it may be - * using this access list */ - ospf_distribute_list_update( - ospf, type, red->instance); + /* Iterate all ospf [VRF] instances */ + for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + /* Update distribute-list, and apply filter. */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (red_list) + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP(red)) { + /* if route-map is not NULL it may be + * using this access list */ + ospf_distribute_list_update( + ospf, + type, red->instance); + } } - } - - /* There is place for route-map for default-information - * (ZEBRA_ROUTE_MAX), - * but no distribute list. */ - if (type == ZEBRA_ROUTE_MAX) - break; - - if (DISTRIBUTE_NAME(ospf, type)) { - /* Keep old access-list for distribute-list. */ - struct access_list *old = DISTRIBUTE_LIST(ospf, type); - - /* Update access-list for distribute-list. */ - DISTRIBUTE_LIST(ospf, type) = access_list_lookup( - AFI_IP, DISTRIBUTE_NAME(ospf, type)); - - /* No update for this distribute type. */ - if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL) - continue; - /* Schedule distribute-list update timer. */ - if (DISTRIBUTE_LIST(ospf, type) == NULL - || strcmp(DISTRIBUTE_NAME(ospf, type), access->name) - == 0) - ospf_distribute_list_update(ospf, type, 0); + /* There is place for route-map for default-information + * (ZEBRA_ROUTE_MAX), + * but no distribute list. */ + if (type == ZEBRA_ROUTE_MAX) + break; + + if (DISTRIBUTE_NAME(ospf, type)) { + /* Keep old access-list for distribute-list. */ + struct access_list *old = DISTRIBUTE_LIST(ospf, + type); + + /* Update access-list for distribute-list. */ + DISTRIBUTE_LIST(ospf, type) = access_list_lookup( + AFI_IP, DISTRIBUTE_NAME(ospf, type)); + + /* No update for this distribute type. */ + if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL) + continue; + + /* Schedule distribute-list update timer. */ + if (DISTRIBUTE_LIST(ospf, type) == NULL + || strcmp(DISTRIBUTE_NAME(ospf, type), access->name) + == 0) + ospf_distribute_list_update(ospf, type, 0); + } } - } - /* Update Area access-list. */ - for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { - if (EXPORT_NAME(area)) { - EXPORT_LIST(area) = NULL; - abr_inv++; - } + /* Update Area access-list. */ + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (EXPORT_NAME(area)) { + EXPORT_LIST(area) = NULL; + abr_inv++; + } - if (IMPORT_NAME(area)) { - IMPORT_LIST(area) = NULL; - abr_inv++; + if (IMPORT_NAME(area)) { + IMPORT_LIST(area) = NULL; + abr_inv++; + } } - } - /* Schedule ABR tasks -- this will be changed -- takada. */ - if (IS_OSPF_ABR(ospf) && abr_inv) - ospf_schedule_abr_task(ospf); + /* Schedule ABR tasks -- this will be changed -- takada. */ + if (IS_OSPF_ABR(ospf) && abr_inv) + ospf_schedule_abr_task(ospf); + } } /* If prefix-list is updated, do some updates. */ void ospf_prefix_list_update(struct prefix_list *plist) { - struct ospf *ospf; + struct ospf *ospf = NULL; int type; int abr_inv = 0; struct ospf_area *area; - struct listnode *node; + struct listnode *node, *n1; /* If OSPF instatnce does not exist, return right now. */ - ospf = ospf_lookup(); - if (ospf == NULL) + if (listcount(om->ospf) == 0) return; - /* Update all route-maps which are used as redistribution filters. - * They might use prefix-list. - */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (red_list) - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { - if (ROUTEMAP(red)) { - /* if route-map is not NULL it may be - * using this prefix list */ - ospf_distribute_list_update( - ospf, type, red->instance); + /* Iterate all ospf [VRF] instances */ + for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) { + + /* Update all route-maps which are used + * as redistribution filters. + * They might use prefix-list. + */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (red_list) { + for (ALL_LIST_ELEMENTS_RO(red_list, + node, red)) { + if (ROUTEMAP(red)) { + /* if route-map is not NULL + * it may be using + * this prefix list */ + ospf_distribute_list_update( + ospf, type, + red->instance); + } } } - } + } - /* Update area filter-lists. */ - for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { - /* Update filter-list in. */ - if (PREFIX_NAME_IN(area)) - if (strcmp(PREFIX_NAME_IN(area), - prefix_list_name(plist)) - == 0) { - PREFIX_LIST_IN(area) = prefix_list_lookup( - AFI_IP, PREFIX_NAME_IN(area)); - abr_inv++; - } + /* Update area filter-lists. */ + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + /* Update filter-list in. */ + if (PREFIX_NAME_IN(area)) + if (strcmp(PREFIX_NAME_IN(area), + prefix_list_name(plist)) == 0) { + PREFIX_LIST_IN(area) = + prefix_list_lookup( + AFI_IP, + PREFIX_NAME_IN(area)); + abr_inv++; + } - /* Update filter-list out. */ - if (PREFIX_NAME_OUT(area)) - if (strcmp(PREFIX_NAME_OUT(area), - prefix_list_name(plist)) - == 0) { - PREFIX_LIST_IN(area) = prefix_list_lookup( - AFI_IP, PREFIX_NAME_OUT(area)); - abr_inv++; - } - } + /* Update filter-list out. */ + if (PREFIX_NAME_OUT(area)) + if (strcmp(PREFIX_NAME_OUT(area), + prefix_list_name(plist)) == 0) { + PREFIX_LIST_IN(area) = + prefix_list_lookup( + AFI_IP, + PREFIX_NAME_OUT(area)); + abr_inv++; + } + } - /* Schedule ABR task. */ - if (IS_OSPF_ABR(ospf) && abr_inv) - ospf_schedule_abr_task(ospf); + /* Schedule ABR task. */ + if (IS_OSPF_ABR(ospf) && abr_inv) + ospf_schedule_abr_task(ospf); + } } static struct ospf_distance *ospf_distance_new(void) @@ -1326,11 +1404,10 @@ void ospf_distance_reset(struct ospf *ospf) } } -u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or) +u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route *or) { - struct ospf *ospf; - ospf = ospf_lookup(); if (ospf == NULL) return 0; @@ -1353,6 +1430,37 @@ u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or) return 0; } +void ospf_zebra_vrf_register(struct ospf *ospf) +{ + if (!zclient || zclient->sock < 0 || !ospf) + return; + + if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Register VRF %s id %u", + __PRETTY_FUNCTION__, + ospf_vrf_id_to_name(ospf->vrf_id), + ospf->vrf_id); + zclient_send_reg_requests(zclient, ospf->vrf_id); + } +} + +void ospf_zebra_vrf_deregister(struct ospf *ospf) +{ + if (!zclient || zclient->sock < 0 || !ospf) + return; + + if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: De-Register VRF %s id %u", + __PRETTY_FUNCTION__, + ospf_vrf_id_to_name(ospf->vrf_id), + ospf->vrf_id); + /* Deregister for router-id, interfaces, + * redistributed routes. */ + zclient_send_dereg_requests(zclient, ospf->vrf_id); + } +} static void ospf_zebra_connected(struct zclient *zclient) { /* Send the client registration */ @@ -1375,6 +1483,7 @@ void ospf_zebra_init(struct thread_master *master, u_short instance) zclient->interface_address_add = ospf_interface_address_add; zclient->interface_address_delete = ospf_interface_address_delete; zclient->interface_link_params = ospf_interface_link_params; + zclient->interface_vrf_update = ospf_interface_vrf_update; zclient->redistribute_route_add = ospf_zebra_read_route; zclient->redistribute_route_del = ospf_zebra_read_route; diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 6fa9e33ddd..8340f49ede 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -41,21 +41,24 @@ struct ospf_distance { }; /* Prototypes */ -extern void ospf_zebra_add(struct prefix_ipv4 *, struct ospf_route *); -extern void ospf_zebra_delete(struct prefix_ipv4 *, struct ospf_route *); +extern void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *, + struct ospf_route *); +extern void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *, + struct ospf_route *); -extern void ospf_zebra_add_discard(struct prefix_ipv4 *); -extern void ospf_zebra_delete_discard(struct prefix_ipv4 *); +extern void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *); +extern void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *); extern int ospf_redistribute_check(struct ospf *, struct external_info *, int *); extern int ospf_distribute_check_connected(struct ospf *, struct external_info *); -extern void ospf_distribute_list_update(struct ospf *, uintptr_t, u_short); +extern void ospf_distribute_list_update(struct ospf *, int, u_short); -extern int ospf_is_type_redistributed(int, u_short); +extern int ospf_is_type_redistributed(struct ospf *, int, u_short); extern void ospf_distance_reset(struct ospf *); -extern u_char ospf_distance_apply(struct prefix_ipv4 *, struct ospf_route *); +extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *, + struct ospf_route *); extern struct ospf_external *ospf_external_lookup(u_char, u_short); extern struct ospf_external *ospf_external_add(u_char, u_short); extern void ospf_external_del(u_char, u_short); @@ -77,6 +80,8 @@ extern int ospf_distance_set(struct vty *, struct ospf *, const char *, extern int ospf_distance_unset(struct vty *, struct ospf *, const char *, const char *, const char *); extern void ospf_zebra_init(struct thread_master *, u_short); +extern void ospf_zebra_vrf_register(struct ospf *ospf); +extern void ospf_zebra_vrf_deregister(struct ospf *ospf); DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index ed1d8901fb..88833e64de 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -67,6 +67,7 @@ struct ospf_master *om; extern struct zclient *zclient; extern struct in_addr router_id_zebra; +extern struct zebra_privs_t ospfd_privs; static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *); @@ -118,6 +119,10 @@ void ospf_router_id_update(struct ospf *ospf) else router_id = router_id_zebra; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Router-ID[OLD:%s]: Update to %s", + inet_ntoa(ospf->router_id), + inet_ntoa(router_id_old)); if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) { @@ -204,7 +209,7 @@ void ospf_router_id_update(struct ospf *ospf) ospf_router_lsa_update(ospf); /* update ospf_interface's */ - for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) ospf_if_update(ospf, ifp); } } @@ -220,9 +225,10 @@ static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2) } /* Allocate new ospf structure. */ -static struct ospf *ospf_new(u_short instance) +static struct ospf *ospf_new(u_short instance, const char *name) { int i; + struct vrf *vrf = NULL; struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf)); @@ -230,6 +236,23 @@ static struct ospf *ospf_new(u_short instance) new->router_id.s_addr = htonl(0); new->router_id_static.s_addr = htonl(0); + if (name) { + new->vrf_id = VRF_UNKNOWN; + /* Freed in ospf_finish_final */ + new->name = XSTRDUP(MTYPE_OSPF_TOP, name); + vrf = vrf_lookup_by_name(new->name); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Create new ospf instance with vrf_name %s vrf_id %d", + __PRETTY_FUNCTION__, name, new->vrf_id); + if (vrf) + ospf_vrf_link(new, vrf); + } else { + new->vrf_id = VRF_DEFAULT; + vrf = vrf_lookup_by_id(VRF_DEFAULT); + ospf_vrf_link(new, vrf); + } + ospf_zebra_vrf_register(new); + new->abr_type = OSPF_ABR_DEFAULT; new->oiflist = list_new(); new->vlinks = list_new(); @@ -286,7 +309,7 @@ static struct ospf *ospf_new(u_short instance) new->lsa_refresh_interval, &new->t_lsa_refresher); new->lsa_refresher_started = monotime(NULL); - if ((new->fd = ospf_sock_init()) < 0) { + if ((ospf_sock_init(new)) < 0) { zlog_err( "ospf_new: fatal error: ospf_sock_init was unable to open " "a socket"); @@ -313,14 +336,6 @@ static struct ospf *ospf_new(u_short instance) return new; } -struct ospf *ospf_lookup() -{ - if (listcount(om->ospf) == 0) - return NULL; - - return listgetdata((struct listnode *)listhead(om->ospf)); -} - struct ospf *ospf_lookup_instance(u_short instance) { struct ospf *ospf; @@ -357,13 +372,33 @@ static void ospf_delete(struct ospf *ospf) listnode_delete(om->ospf, ospf); } -struct ospf *ospf_get() +struct ospf *ospf_lookup_by_inst_name(u_short instance, const char *name) +{ + struct ospf *ospf = NULL; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) { + if ((ospf->instance == instance) && + ((ospf->name == NULL && name == NULL) || + (ospf->name && name && strcmp(ospf->name, name) == 0))) + return ospf; + } + return NULL; +} + +struct ospf *ospf_get(u_short instance, const char *name) { struct ospf *ospf; - ospf = ospf_lookup(); + /* vrf name provided call inst and name based api + * in case of no name pass default ospf instance */ + if (name) + ospf = ospf_lookup_by_inst_name(instance, name); + else + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL) { - ospf = ospf_new(0); + ospf = ospf_new(instance, name); ospf_add(ospf); if (ospf->router_id_static.s_addr == 0) @@ -381,11 +416,20 @@ struct ospf *ospf_get_instance(u_short instance) ospf = ospf_lookup_instance(instance); if (ospf == NULL) { - ospf = ospf_new(instance); + ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/); ospf_add(ospf); - if (ospf->router_id_static.s_addr == 0) + if (ospf->router_id_static.s_addr == 0) { + if (vrf_lookup_by_id(ospf->vrf_id)) + ospf_router_id_update(ospf); + else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ospf VRF (id %d) is not active yet, skip router id update" + , __PRETTY_FUNCTION__, + ospf->vrf_id); + } ospf_router_id_update(ospf); + } ospf_opaque_type11_lsa_init(ospf); } @@ -393,6 +437,34 @@ struct ospf *ospf_get_instance(u_short instance) return ospf; } +struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id) +{ + struct vrf *vrf = NULL; + + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + return (vrf->info) ? (struct ospf *)vrf->info : NULL; + +} + +/* It should only be used when processing incoming info update from zebra. + * Other situations, it is not sufficient to lookup the ospf instance by + * vrf_name only without using the instance number. + */ +static struct ospf *ospf_lookup_by_name(const char *vrf_name) +{ + struct ospf *ospf = NULL; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) + if ((ospf->name == NULL && vrf_name == NULL) + || (ospf->name && vrf_name && + strcmp(ospf->name, vrf_name) == 0)) + return ospf; + return NULL; +} + /* Handle the second half of deferred shutdown. This is called either * from the deferred-shutdown timer thread, or directly through * ospf_deferred_shutdown_check. @@ -519,6 +591,7 @@ 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); @@ -547,10 +620,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(VRF_DEFAULT), node, ifp)) { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) { struct ospf_if_params *params; params = IF_DEF_PARAMS(ifp); @@ -561,6 +634,10 @@ 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); /* Clear static neighbors */ for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) @@ -639,7 +716,7 @@ static void ospf_finish_final(struct ospf *ospf) if (ospf->old_table) ospf_route_table_free(ospf->old_table); if (ospf->new_table) { - ospf_route_delete(ospf->new_table); + ospf_route_delete(ospf, ospf->new_table); ospf_route_table_free(ospf->new_table); } if (ospf->old_rtrs) @@ -647,20 +724,19 @@ static void ospf_finish_final(struct ospf *ospf) if (ospf->new_rtrs) ospf_rtrs_free(ospf->new_rtrs); if (ospf->new_external_route) { - ospf_route_delete(ospf->new_external_route); + ospf_route_delete(ospf, ospf->new_external_route); ospf_route_table_free(ospf->new_external_route); } if (ospf->old_external_route) { - ospf_route_delete(ospf->old_external_route); + ospf_route_delete(ospf, ospf->old_external_route); ospf_route_table_free(ospf->old_external_route); } if (ospf->external_lsas) { 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; @@ -694,6 +770,17 @@ static void ospf_finish_final(struct ospf *ospf) ospf_delete(ospf); + if (ospf->name) { + vrf = vrf_lookup_by_name(ospf->name); + if (vrf) + ospf_vrf_unlink(ospf, vrf); + XFREE(MTYPE_OSPF_TOP, ospf->name); + } else { + vrf = vrf_lookup_by_id(VRF_DEFAULT); + if (vrf) + ospf_vrf_unlink(ospf, vrf); + } + XFREE(MTYPE_OSPF_TOP, ospf); if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) @@ -741,6 +828,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); @@ -765,7 +854,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)); @@ -883,7 +972,7 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf) struct external_info *ei; struct ospf_external *ext; - if (ospf_is_type_redistributed(ZEBRA_ROUTE_CONNECT, 0)) + if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) && EXTERNAL_INFO(ext)) { for (rn = route_top(EXTERNAL_INFO(ext)); rn; @@ -1004,9 +1093,10 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p, * * Otherwise, doesn't do anything different to ospf_if_update for now */ -void ospf_interface_area_set(struct interface *ifp) +void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp) { - struct ospf *ospf = ospf_get(); + if (!ospf) + return; ospf_if_update(ospf, ifp); /* if_update does a update_redistributed */ @@ -1014,19 +1104,17 @@ void ospf_interface_area_set(struct interface *ifp) return; } -void ospf_interface_area_unset(struct interface *ifp) +void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp) { struct route_node *rn_oi; - struct ospf *ospf; - ospf = ospf_lookup(); if (!ospf) return; /* Ospf not ready yet */ /* Find interfaces that may need to be removed. */ for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi; rn_oi = route_next(rn_oi)) { - struct ospf_interface *oi; + struct ospf_interface *oi = NULL; if ((oi = rn_oi->info) == NULL) continue; @@ -1174,7 +1262,7 @@ static void ospf_network_run(struct prefix *p, struct ospf_area *area) ospf_router_id_update(area->ospf); /* Get target interface. */ - for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(area->ospf->vrf_id), node, ifp)) ospf_network_run_interface(area->ospf, ifp, p, area); } @@ -1190,7 +1278,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; } @@ -1203,8 +1291,15 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi) void ospf_if_update(struct ospf *ospf, struct interface *ifp) { + if (!ospf) - ospf = ospf_lookup(); + return; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s", + __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id, + ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id, + inet_ntoa(ospf->router_id)); /* OSPF must be ready. */ if (!ospf_is_ready(ospf)) @@ -1863,3 +1958,128 @@ void ospf_master_init(struct thread_master *master) om->ospf = list_new(); om->master = master; } + +/* Link OSPF instance to VRF. */ +void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf) +{ + ospf->vrf_id = vrf->vrf_id; + if (vrf->info != (void *)ospf) + vrf->info = (void *)ospf; +} + +/* Unlink OSPF instance from VRF. */ +void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf) +{ + if (vrf->info == (void *)ospf) + vrf->info = NULL; + ospf->vrf_id = VRF_UNKNOWN; +} + +/* This is hook function for vrf create called as part of vrf_init */ +static int ospf_vrf_new(struct vrf *vrf) +{ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: VRF Created: %s(%d)", __PRETTY_FUNCTION__, + vrf->name, vrf->vrf_id); + + return 0; +} + +/* This is hook function for vrf delete call as part of vrf_init */ +static int ospf_vrf_delete(struct vrf *vrf) +{ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: VRF Deletion: %s(%d)", __PRETTY_FUNCTION__, + vrf->name, vrf->vrf_id); + + return 0; +} + +/* Enable OSPF VRF instance */ +static int ospf_vrf_enable(struct vrf *vrf) +{ + struct ospf *ospf = NULL; + vrf_id_t old_vrf_id = VRF_DEFAULT; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: VRF %s id %d enabled", + __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id); + + ospf = ospf_lookup_by_name(vrf->name); + if (ospf) { + old_vrf_id = ospf->vrf_id; + /* We have instance configured, link to VRF and make it "up". */ + ospf_vrf_link(ospf, vrf); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ospf linked to vrf %s vrf_id %d (old id %d)", + __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id, + old_vrf_id); + + if (old_vrf_id != ospf->vrf_id) { + if (ospfd_privs.change(ZPRIVS_RAISE)) { + zlog_err("ospf_sock_init: could not raise privs, %s", + safe_strerror(errno)); + } + if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0) + return 0; + if (ospfd_privs.change(ZPRIVS_LOWER)) { + zlog_err("ospf_sock_init: could not lower privs, %s", + safe_strerror(errno)); + } + + ospf->oi_running = 1; + ospf_router_id_update(ospf); + } + } + + return 0; +} + +/* Disable OSPF VRF instance */ +static int ospf_vrf_disable(struct vrf *vrf) +{ + struct ospf *ospf = NULL; + vrf_id_t old_vrf_id = VRF_UNKNOWN; + + if (vrf->vrf_id == VRF_DEFAULT) + return 0; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: VRF %s id %d disabled.", + __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id); + + ospf = ospf_lookup_by_name(vrf->name); + if (ospf) { + old_vrf_id = ospf->vrf_id; + + /* We have instance configured, unlink + * from VRF and make it "down". + */ + ospf_vrf_unlink(ospf, vrf); + ospf->oi_running = 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ospf old_vrf_id %d unlinked", + __PRETTY_FUNCTION__, old_vrf_id); + } + + /* Note: This is a callback, the VRF will be deleted by the caller. */ + return 0; +} + +void ospf_vrf_init(void) +{ + vrf_init(ospf_vrf_new, ospf_vrf_enable, + ospf_vrf_disable, ospf_vrf_delete); +} + +void ospf_vrf_terminate(void) +{ + vrf_terminate(); +} + +const char *ospf_vrf_id_to_name(vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + + return vrf ? vrf->name : "NIL"; +} diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b49bbdc17d..01147c2004 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -28,6 +28,7 @@ #include "filter.h" #include "log.h" +#include "vrf.h" #include "ospf_memory.h" #include "ospf_dump_api.h" @@ -92,8 +93,6 @@ struct ospf_master { /* OSPF thread master. */ struct thread_master *master; - /* Zebra interface list. */ - struct list *iflist; /* Redistributed external information. */ struct list *external[ZEBRA_ROUTE_MAX + 1]; @@ -136,6 +135,9 @@ struct ospf { struct in_addr router_id; /* Configured automatically. */ struct in_addr router_id_static; /* Configured manually. */ + vrf_id_t vrf_id; /* VRF Id */ + char *name; /* VRF name */ + /* ABR/ASBR internal flags. */ u_char flags; #define OSPF_FLAG_ABR 0x0001 @@ -503,10 +505,12 @@ extern int ospf_zlog; /* Prototypes. */ extern const char *ospf_redist_string(u_int route_type); -extern struct ospf *ospf_lookup(void); extern struct ospf *ospf_lookup_instance(u_short); -extern struct ospf *ospf_get(void); +extern struct ospf *ospf_get(u_short instance, const char *name); extern struct ospf *ospf_get_instance(u_short); +extern struct ospf *ospf_lookup_by_inst_name(u_short instance, + const char *name); +extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id); extern void ospf_finish(struct ospf *); extern void ospf_router_id_update(struct ospf *ospf); extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr, @@ -559,11 +563,15 @@ extern struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *, extern void ospf_area_add_if(struct ospf_area *, struct ospf_interface *); extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *); -extern void ospf_interface_area_set(struct interface *); -extern void ospf_interface_area_unset(struct interface *); +extern void ospf_interface_area_set(struct ospf *, struct interface *); +extern void ospf_interface_area_unset(struct ospf *, struct interface *); extern void ospf_route_map_init(void); extern void ospf_master_init(struct thread_master *master); - +extern void ospf_vrf_init(void); +extern void ospf_vrf_terminate(void); +extern void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf); +extern void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf); +const char *ospf_vrf_id_to_name(vrf_id_t vrf_id); #endif /* _ZEBRA_OSPFD_H */ diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 12c2313e65..e063415fbd 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -58,6 +58,9 @@ ospfdheader_HEADERS = \ # end endif +ospfd/ospf_vty_clippy.c: $(CLIPPY_DEPS) +ospfd/ospf_vty.$(OBJEXT): ospfd/ospf_vty_clippy.c + noinst_HEADERS += \ ospfd/ospf_abr.h \ ospfd/ospf_apiserver.h \ diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 1ebe9c9aba..ed1d6a8195 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1063,58 +1063,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 +1227,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) { @@ -2400,6 +2386,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); @@ -3160,12 +3170,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, @@ -4451,7 +4461,8 @@ DEFUN (show_ip_multicast_vrf_all, return CMD_SUCCESS; } -static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj) +static void show_mroute(struct pim_instance *pim, struct vty *vty, + bool fill, u_char uj) { struct listnode *node; struct channel_oil *c_oil; @@ -4704,11 +4715,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj) continue; ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index); - pim_time_uptime( - oif_uptime, sizeof(oif_uptime), - now - - s_route->c_oil - .oif_creation[oif_vif_index]); + pim_time_uptime(oif_uptime, sizeof(oif_uptime), + now - + s_route->c_oil.oif_creation[oif_vif_index]); found_oif = 1; if (ifp_out) @@ -4751,7 +4760,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj) src_str, grp_str, proto, in_ifname, out_ifname, ttl, oif_uptime, pim->vrf->name); - if (first) { + if (first && !fill) { src_str[0] = '\0'; grp_str[0] = '\0'; in_ifname[0] = '\0'; @@ -4777,36 +4786,47 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj) DEFUN (show_ip_mroute, show_ip_mroute_cmd, - "show ip mroute [vrf NAME] [json]", + "show ip mroute [vrf NAME] [fill] [json]", SHOW_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR + "Fill in Assumed data\n" JSON_STR) { u_char uj = use_json(argc, argv); + bool fill = false; int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); if (!vrf) return CMD_WARNING; - show_mroute(vrf->info, vty, uj); + if (argv_find(argv, argc, "fill", &idx)) + fill = true; + + show_mroute(vrf->info, vty, fill, uj); return CMD_SUCCESS; } DEFUN (show_ip_mroute_vrf_all, show_ip_mroute_vrf_all_cmd, - "show ip mroute vrf all [json]", + "show ip mroute vrf all [fill] [json]", SHOW_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR + "Fill in Assumed data\n" JSON_STR) { u_char uj = use_json(argc, argv); + int idx = 4; struct vrf *vrf; bool first = true; + bool fill = false; + + if (argv_find(argv, argc, "fill", &idx)) + fill = true; if (uj) vty_out(vty, "{ "); @@ -4818,7 +4838,7 @@ DEFUN (show_ip_mroute_vrf_all, first = false; } else vty_out(vty, "VRF: %s\n", vrf->name); - show_mroute(vrf->info, vty, uj); + show_mroute(vrf->info, vty, fill, uj); } if (uj) vty_out(vty, "}\n"); @@ -6470,7 +6490,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; @@ -6498,11 +6518,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..8787145027 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); @@ -1373,7 +1373,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; } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index bcf7d2318d..6aa5105c5f 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); 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..7de3e4ca6c 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); } 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 1e88ff13ff..a1de4837db 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -194,7 +194,7 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr, } if (up != NULL) - up = hash_get(pnc->upstream_hash, up, hash_alloc_intern); + hash_get(pnc->upstream_hash, up, hash_alloc_intern); if (pnc && CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) { memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache)); @@ -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); 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..cb722c17b2 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); } /* 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..ed5d1ecaa2 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); @@ -1548,8 +1546,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..fc377b5a52 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -362,7 +362,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/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_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..bededba7fc 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); } @@ -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); } 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_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..7524061ad2 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. @@ -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) @@ -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); } @@ -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); } 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/tests/isisd/test_isis_vertex_queue.c b/tests/isisd/test_isis_vertex_queue.c index 50436387b5..674482cd17 100644 --- a/tests/isisd/test_isis_vertex_queue.c +++ b/tests/isisd/test_isis_vertex_queue.c @@ -89,7 +89,7 @@ static void test_ordered(void) assert(isis_vertex_queue_pop(&q) == vertices[1]); assert(isis_find_vertex(&q, vertices[1]->N.id, vertices[1]->type) == NULL); - assert(isis_vertex_queue_pop(&q) == vertices[4]); + isis_vertex_queue_delete(&q, vertices[4]); assert(isis_find_vertex(&q, vertices[4]->N.id, vertices[4]->type) == NULL); assert(isis_vertex_queue_count(&q) == 0); 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/tools/frr-reload.py b/tools/frr-reload.py index afe66b6eaf..e19eeb04ee 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -940,6 +940,32 @@ def compare_context_objects(newconf, running): return (lines_to_add, lines_to_del) + +def vtysh_config_available(): + """ + Return False if no frr daemon is running or some other vtysh session is + in 'configuration terminal' mode which will prevent us from making any + configuration changes. + """ + + try: + cmd = ['/usr/bin/vtysh', '-c', 'conf t'] + output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip() + + if 'VTY configuration is locked by other VTY' in output: + print output + log.error("'%s' returned\n%s\n" % (' '.join(cmd), output)) + return False + + except subprocess.CalledProcessError as e: + msg = "vtysh could not connect with any frr daemons" + print msg + log.error(msg) + return False + + return True + + if __name__ == '__main__': # Command line options parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs') @@ -1060,6 +1086,10 @@ if __name__ == '__main__': elif args.reload: + # We will not be able to do anything, go ahead and exit(1) + if not vtysh_config_available(): + sys.exit(1) + log.debug('New Frr Config\n%s', newconf.get_lines()) # This looks a little odd but we have to do this twice...here is why diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 3f86f3c929..061c25cea5 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -226,7 +226,8 @@ static int vtysh_client_run_all(struct vtysh_client *head_client, wrong_instance++; continue; } - correct_instance++; + if (client->fd > 0) + correct_instance++; if (rc != CMD_SUCCESS) { if (!continue_on_err) return rc; @@ -423,13 +424,22 @@ static int vtysh_execute_func(const char *line, int pager) } cmd_stat = CMD_SUCCESS; + struct vtysh_client *vc; for (i = 0; i < array_size(vtysh_client); i++) { if (cmd->daemon & vtysh_client[i].flag) { if (vtysh_client[i].fd < 0 && (cmd->daemon == vtysh_client[i].flag)) { - fprintf(stderr, "%s is not running\n", - vtysh_client[i].name); - continue; + bool any_inst = false; + for (vc = &vtysh_client[i]; vc; + vc = vc->next) + any_inst = any_inst + || (vc->fd > 0); + if (!any_inst) { + fprintf(stderr, + "%s is not running\n", + vtysh_client[i].name); + continue; + } } cmd_stat = vtysh_client_execute( &vtysh_client[i], line, fp); @@ -1263,10 +1273,12 @@ DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng", return CMD_SUCCESS; } -DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, "router ospf [(1-65535)]", +DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, + "router ospf [(1-65535)] [vrf NAME]", "Enable a routing process\n" "Start OSPF configuration\n" - "Instance ID\n") + "Instance ID\n" + VRF_CMD_HELP_STR) { vty->node = OSPF_NODE; return CMD_SUCCESS; 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 003853571f..8509a8a05a 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -404,9 +404,9 @@ int main(int argc, char **argv, char **env) "NOT SUPPORTED since its\nresults are inconsistent!\n"); } - snprintf(vtysh_config, sizeof(vtysh_config), "%s%s/%s", sysconfdir, + snprintf(vtysh_config, sizeof(vtysh_config), "%s%s%s", sysconfdir, pathspace, VTYSH_CONFIG_NAME); - snprintf(frr_config, sizeof(frr_config), "%s%s/%s", sysconfdir, + snprintf(frr_config, sizeof(frr_config), "%s%s%s", sysconfdir, pathspace, FRR_CONFIG_NAME); strlcat(vtydir, pathspace, sizeof(vtydir)); @@ -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/interface.c b/zebra/interface.c index 664e493d84..a65dd21f63 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) { diff --git a/zebra/irdp.h b/zebra/irdp.h index ea190b574d..8aa9f3e4b3 100644 --- a/zebra/irdp.h +++ b/zebra/irdp.h @@ -111,6 +111,8 @@ */ struct irdp_interface { + bool started; + unsigned long MaxAdvertInterval; unsigned long MinAdvertInterval; unsigned long Preference; diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 34c78e2a48..8234ed6bdd 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -63,11 +63,28 @@ extern int irdp_sock; DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data") +#define IRDP_CONFIGED \ + do { \ + if (!irdp) { \ + vty_out(vty, "Please Configure IRDP before using this command\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + } \ + } \ + while (0) + static struct irdp_interface *irdp_if_get(struct interface *ifp) { struct zebra_if *zi = ifp->info; + + if (!zi) + return NULL; + if (!zi->irdp) zi->irdp = XCALLOC(MTYPE_IRDP_IF, sizeof(*zi->irdp)); + + if (!zi->irdp->started) + return NULL; + return zi->irdp; } @@ -203,6 +220,7 @@ static void irdp_if_start(struct interface *ifp, int multicast, assert(irdp); + irdp->started = true; if (irdp->flags & IF_ACTIVE) { zlog_warn("IRDP: Interface is already active %s", ifp->name); return; @@ -293,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; } @@ -307,6 +324,7 @@ static void irdp_if_shutdown(struct interface *ifp) if (!irdp) return; + if (irdp->flags & IF_SHUTDOWN) { zlog_warn("IRDP: Interface is already shutdown %s", ifp->name); return; @@ -326,6 +344,9 @@ static void irdp_if_no_shutdown(struct interface *ifp) { struct irdp_interface *irdp = irdp_if_get(ifp); + if (!irdp) + return; + if (!(irdp->flags & IF_SHUTDOWN)) { zlog_warn("IRDP: Interface is not shutdown %s", ifp->name); return; @@ -458,6 +479,8 @@ DEFUN (ip_irdp_holdtime, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + irdp->Lifetime = atoi(argv[idx_number]->arg); return CMD_SUCCESS; } @@ -474,6 +497,8 @@ DEFUN (ip_irdp_minadvertinterval, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) { irdp->MinAdvertInterval = atoi(argv[idx_number]->arg); return CMD_SUCCESS; @@ -497,6 +522,8 @@ DEFUN (ip_irdp_maxadvertinterval, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) { irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg); return CMD_SUCCESS; @@ -525,6 +552,8 @@ DEFUN (ip_irdp_preference, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + irdp->Preference = atoi(argv[idx_number]->arg); return CMD_SUCCESS; } @@ -549,6 +578,8 @@ DEFUN (ip_irdp_address_preference, int ret; struct Adv *adv; + IRDP_CONFIGED; + ret = inet_aton(argv[idx_ipv4]->arg, &ip); if (!ret) return CMD_WARNING_CONFIG_FAILED; @@ -586,6 +617,8 @@ DEFUN (no_ip_irdp_address_preference, int ret; struct Adv *adv; + IRDP_CONFIGED; + ret = inet_aton(argv[idx_ipv4]->arg, &ip); if (!ret) return CMD_WARNING_CONFIG_FAILED; @@ -611,6 +644,8 @@ DEFUN (ip_irdp_debug_messages, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + irdp->flags |= IF_DEBUG_MESSAGES; return CMD_SUCCESS; @@ -627,6 +662,8 @@ DEFUN (ip_irdp_debug_misc, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + irdp->flags |= IF_DEBUG_MISC; return CMD_SUCCESS; @@ -643,6 +680,8 @@ DEFUN (ip_irdp_debug_packet, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + irdp->flags |= IF_DEBUG_PACKET; return CMD_SUCCESS; @@ -660,6 +699,8 @@ DEFUN (ip_irdp_debug_disable, VTY_DECLVAR_CONTEXT(interface, ifp); struct irdp_interface *irdp = irdp_if_get(ifp); + IRDP_CONFIGED; + irdp->flags &= ~IF_DEBUG_PACKET; irdp->flags &= ~IF_DEBUG_MESSAGES; irdp->flags &= ~IF_DEBUG_MISC; diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 015e11b3a5..a5c36b0dae 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -676,16 +676,21 @@ int netlink_talk(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, ns_id_t, { int status; struct sockaddr_nl snl; - struct iovec iov = {.iov_base = (void *)n, .iov_len = n->nlmsg_len}; - struct msghdr msg = { - .msg_name = (void *)&snl, - .msg_namelen = sizeof snl, - .msg_iov = &iov, - .msg_iovlen = 1, - }; + struct iovec iov; + struct msghdr msg; int save_errno; memset(&snl, 0, sizeof snl); + memset(&iov, 0, sizeof iov); + memset(&msg, 0, sizeof msg); + + iov.iov_base = n; + iov.iov_len = n->nlmsg_len; + msg.msg_name = (void *)&snl; + msg.msg_namelen = sizeof snl; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + snl.nl_family = AF_NETLINK; n->nlmsg_seq = ++nl->seq; 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 4864b4961d..5a2979c866 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -127,8 +127,8 @@ static void sigint(void) frr_early_fini(); - zebra_ptm_finish(); list_delete_all_node(zebrad.client_list); + zebra_ptm_finish(); if (retain_mode) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { @@ -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 6091c75e50..633604120c 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -176,11 +176,13 @@ static void rtadv_send_packet(int sock, struct interface *ifp) */ if (adata == NULL) { /* XXX Free on shutdown. */ - adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo))); + adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo))); - if (adata == NULL) + if (adata == NULL) { zlog_err( "rtadv_send_packet: can't malloc control data"); + exit(-1); + } } /* Logging of packet. */ 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_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 4bc9caca5d..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); } @@ -304,6 +304,7 @@ static void addr2hostprefix(int af, const union g_addr *addr, prefix->u.prefix6 = addr->ipv6; break; default: + memset(prefix, 0, sizeof(*prefix)); zlog_warn("%s: unknown address family %d", __func__, af); break; } 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..bd7b3cb8d0 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; @@ -1225,15 +1233,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 +1266,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 +1303,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 +1310,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 +1320,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 +1339,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 +1354,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 +1371,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 +1384,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 +1396,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 +1416,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 +1441,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 +1457,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 +1470,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 +1483,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 +1569,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 +1599,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 +1637,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 +1647,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 +1674,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 +1716,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 +1731,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 +1768,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 +1787,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 +1802,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 +1822,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 +1849,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 +1861,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 +1970,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 +1981,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 +2003,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 +2044,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 +2062,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 +2089,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 +2118,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 +2131,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 +2139,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 +2150,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 +2163,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 +2181,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 +2207,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 +2233,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 +2359,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 +2383,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 +2437,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 +2467,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 +2510,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 +2551,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 +2561,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 +2603,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 +2634,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 +2663,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 +2693,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 +2703,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 +2741,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 +2773,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 +2819,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 +2837,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 +2850,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 +2866,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 +2894,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 +2905,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 +2919,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 +2957,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 +2990,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 +3006,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 +3016,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 +3070,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 +3116,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 +3149,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 +3220,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 +3258,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 +3284,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 +3307,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 +3335,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 +3381,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 +3393,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 +3413,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 +3446,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 +3457,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 +3476,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 +3492,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 +3508,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 +3521,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 +3553,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 +3564,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 +3579,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 +3604,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 +3636,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 +3661,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 +3684,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 +3701,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 +3762,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 +3779,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 +3813,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 +3838,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 +3864,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 +3916,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 +3970,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 +3988,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 +4002,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 +4035,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 +4049,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 +4066,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 +4080,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 +4094,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 +4132,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 +4146,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 +4167,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 +4179,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 +4196,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 +4229,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 +4244,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 +4269,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 +4290,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 +4313,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 +4328,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 +4355,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 +4395,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 +4451,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..f888207818 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( |
