X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=zebra%2Fzebra_vxlan.c;h=4b56581ca9ba7282f30c0a3893caf071847bccbb;hb=f94ed830df98218447f00b97f856de811bfcc4a2;hp=1da419040ed6c352cd30daee20595d698487b63b;hpb=28ad0501b9758080d23cf581d0210eeceeec9ded;p=mirror_frr.git diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 1da419040..4b56581ca 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1994,6 +1994,7 @@ struct zvni_evpn_show { struct vty *vty; json_object *json; struct zebra_vrf *zvrf; + bool use_json; }; /* print a L3 VNI hash entry in detail*/ @@ -2001,20 +2002,21 @@ static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data) { struct vty *vty = NULL; zebra_l3vni_t *zl3vni = NULL; - json_object *json = NULL; + json_object *json_array = NULL; bool use_json = false; struct zvni_evpn_show *zes = data; vty = zes->vty; - json = zes->json; - - if (json) - use_json = true; + json_array = zes->json; + use_json = zes->use_json; zl3vni = (zebra_l3vni_t *)bucket->data; - zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni, use_json); - vty_out(vty, "\n"); + zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni, + use_json, json_array); + + if (!use_json) + vty_out(vty, "\n"); } @@ -2089,20 +2091,20 @@ static void zvni_print_hash_detail(struct hash_bucket *bucket, void *data) { struct vty *vty; zebra_vni_t *zvni; - json_object *json = NULL; + json_object *json_array = NULL; bool use_json = false; struct zvni_evpn_show *zes = data; vty = zes->vty; - json = zes->json; - - if (json) - use_json = true; + json_array = zes->json; + use_json = zes->use_json; zvni = (zebra_vni_t *)bucket->data; - zebra_vxlan_print_vni(vty, zes->zvrf, zvni->vni, use_json); - vty_out(vty, "\n"); + zebra_vxlan_print_vni(vty, zes->zvrf, zvni->vni, use_json, json_array); + + if (!use_json) + vty_out(vty, "\n"); } /* @@ -3210,7 +3212,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, vtep_ip = n->r_vtep_ip; /* Mark appropriately */ UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE); - n->r_vtep_ip.s_addr = 0; + n->r_vtep_ip.s_addr = INADDR_ANY; SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); n->ifindex = ifp->ifindex; } @@ -7285,9 +7287,14 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, /* * Display VNI information (VTY command handler). + * + * use_json flag indicates that output should be in JSON format. + * json_array is non NULL when JSON output needs to be aggregated (by the + * caller) and then printed, otherwise, JSON evpn vni info is printed + * right away. */ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, - bool use_json) + bool use_json, json_object *json_array) { json_object *json = NULL; void *args[2]; @@ -7299,6 +7306,7 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, if (use_json) json = json_object_new_object(); + args[0] = vty; args[1] = json; @@ -7307,21 +7315,25 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, zl3vni_print(zl3vni, (void *)args); } else { zvni = zvni_lookup(vni); - if (!zvni) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "%% VNI %u does not exist\n", vni); - return; - } - - zvni_print(zvni, (void *)args); + if (zvni) + zvni_print(zvni, (void *)args); + else if (!json) + vty_out(vty, "%% VNI %u does not exist\n", vni); } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); + /* + * Each "json" object contains info about 1 VNI. + * When "json_array" is non-null, we aggreggate the json output + * into json_array and print it as a JSON array. + */ + if (json_array) + json_object_array_add(json_array, json); + else { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } } } @@ -7478,7 +7490,7 @@ stream_failure: void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf, bool use_json) { - json_object *json = NULL; + json_object *json_array = NULL; struct zebra_ns *zns = NULL; struct zvni_evpn_show zes; @@ -7489,13 +7501,13 @@ void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf, if (!zns) return; - if (use_json) - json = json_object_new_object(); + json_array = json_object_new_array(); zes.vty = vty; - zes.json = json; + zes.json = json_array; zes.zvrf = zvrf; + zes.use_json = use_json; /* Display all L2-VNIs */ hash_iterate( @@ -7512,8 +7524,8 @@ void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf, if (use_json) { vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); } } @@ -7670,6 +7682,55 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp, return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state); } +static int32_t +zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni, + struct ethaddr *macaddr, uint16_t *ipa_len, + struct ipaddr *ip, struct in_addr *vtep_ip, + uint8_t *flags, uint32_t *seq) +{ + uint16_t l = 0; + + /* + * Obtain each remote MACIP and process. + * Message contains VNI, followed by MAC followed by IP (if any) + * followed by remote VTEP IP. + */ + memset(ip, 0, sizeof(*ip)); + STREAM_GETL(s, *vni); + STREAM_GET(macaddr->octet, s, ETH_ALEN); + STREAM_GETL(s, *ipa_len); + + if (*ipa_len) { + if (*ipa_len == IPV4_MAX_BYTELEN) + ip->ipa_type = IPADDR_V4; + else if (*ipa_len == IPV6_MAX_BYTELEN) + ip->ipa_type = IPADDR_V6; + else { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "ipa_len *must* be %d or %d bytes in length not %d", + IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN, + *ipa_len); + goto stream_failure; + } + + STREAM_GET(&ip->ip.addr, s, *ipa_len); + } + l += 4 + ETH_ALEN + 4 + *ipa_len; + STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN); + l += IPV4_MAX_BYTELEN; + + if (add) { + STREAM_GETC(s, *flags); + STREAM_GETL(s, *seq); + l += 5; + } + + return l; + +stream_failure: + return -1; +} /* * Handle message from client to delete a remote MACIP for a VNI. @@ -7692,23 +7753,14 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) s = msg; while (l < hdr->length) { - /* Obtain each remote MACIP and process. */ - /* Message contains VNI, followed by MAC followed by IP (if any) - * followed by remote VTEP IP. - */ - memset(&ip, 0, sizeof(ip)); - STREAM_GETL(s, vni); - STREAM_GET(&macaddr.octet, s, ETH_ALEN); - STREAM_GETL(s, ipa_len); - if (ipa_len) { - ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 - : IPADDR_V6; - STREAM_GET(&ip.ip.addr, s, ipa_len); - } - l += 4 + ETH_ALEN + 4 + ipa_len; - STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN); - l += IPV4_MAX_BYTELEN; + int res_length = zebra_vxlan_remote_macip_helper( + false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL, + NULL); + + if (res_length == -1) + goto stream_failure; + l += res_length; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s", @@ -7757,29 +7809,14 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) s = msg; while (l < hdr->length) { - /* Obtain each remote MACIP and process. */ - /* Message contains VNI, followed by MAC followed by IP (if any) - * followed by remote VTEP IP. - */ - memset(&ip, 0, sizeof(ip)); - STREAM_GETL(s, vni); - STREAM_GET(&macaddr.octet, s, ETH_ALEN); - STREAM_GETL(s, ipa_len); - if (ipa_len) { - ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 - : IPADDR_V6; - STREAM_GET(&ip.ip.addr, s, ipa_len); - } - l += 4 + ETH_ALEN + 4 + ipa_len; - STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN); - l += IPV4_MAX_BYTELEN; + int res_length = zebra_vxlan_remote_macip_helper( + true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, + &flags, &seq); - /* Get flags - sticky mac and/or gateway mac */ - STREAM_GETC(s, flags); - l++; - STREAM_GETL(s, seq); - l += 4; + if (res_length == -1) + goto stream_failure; + l += res_length; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s", @@ -8582,6 +8619,16 @@ void zebra_vxlan_macvlan_down(struct interface *ifp) zif = ifp->info; assert(zif); link_ifp = zif->link; + if (!link_ifp) { + if (IS_ZEBRA_DEBUG_VXLAN) { + struct interface *ifp; + + ifp = if_lookup_by_index_all_vrf(zif->link_ifindex); + zlog_debug("macvlan parent link is not found. Parent index %d ifp %s", + zif->link_ifindex, ifp ? ifp->name : " "); + } + return; + } link_zif = link_ifp->info; assert(link_zif); @@ -9439,7 +9486,7 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) s = msg; STREAM_GETC(s, advertise); - vni = stream_get3(s); + STREAM_GET(&vni, s, 3); zvni = zvni_lookup(vni); if (!zvni) @@ -9938,7 +9985,7 @@ static zebra_vxlan_sg_t *zebra_vxlan_sg_add(struct zebra_vrf *zvrf, * 2. the XG entry is used by pimd to setup the * vxlan-termination-mroute */ - if (sg->src.s_addr) { + if (sg->src.s_addr != INADDR_ANY) { memset(&sip, 0, sizeof(sip)); parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp); if (!parent) @@ -9970,7 +10017,7 @@ static void zebra_vxlan_sg_del(zebra_vxlan_sg_t *vxlan_sg) /* On SG entry deletion remove the reference to its parent XG * entry */ - if (vxlan_sg->sg.src.s_addr) { + if (vxlan_sg->sg.src.s_addr != INADDR_ANY) { memset(&sip, 0, sizeof(sip)); zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp); } @@ -10029,7 +10076,8 @@ static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, { struct zebra_vrf *zvrf; - if (!local_vtep_ip.s_addr || !mcast_grp.s_addr) + if (local_vtep_ip.s_addr == INADDR_ANY + || mcast_grp.s_addr == INADDR_ANY) return; zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -10044,7 +10092,8 @@ static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, { struct zebra_vrf *zvrf; - if (!local_vtep_ip.s_addr || !mcast_grp.s_addr) + if (local_vtep_ip.s_addr == INADDR_ANY + || mcast_grp.s_addr == INADDR_ANY) return; zvrf = vrf_info_lookup(VRF_DEFAULT);