diff options
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/if_netlink.c | 4 | ||||
| -rw-r--r-- | zebra/interface.c | 5 | ||||
| -rw-r--r-- | zebra/interface.h | 2 | ||||
| -rw-r--r-- | zebra/ioctl.c | 8 | ||||
| -rw-r--r-- | zebra/kernel_netlink.c | 12 | ||||
| -rw-r--r-- | zebra/kernel_socket.c | 35 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mac.c | 13 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mac.h | 4 | ||||
| -rw-r--r-- | zebra/zebra_netns_notify.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_rnh.c | 27 | ||||
| -rw-r--r-- | zebra/zebra_rnh.h | 8 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 12 | ||||
| -rw-r--r-- | zebra/zebra_vxlan.c | 169 |
14 files changed, 199 insertions, 104 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index fca03e55bf..873aea236d 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -103,7 +103,7 @@ static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, EC_LIB_INTERFACE, "interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!", ifi_index, oifp->name, ifp->name); - if_delete_update(oifp); + if_delete_update(&oifp); } } if_set_index(ifp, ifi_index); @@ -2144,7 +2144,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) else if (IS_ZEBRA_IF_VXLAN(ifp)) zebra_l2_vxlanif_del(ifp); - if_delete_update(ifp); + if_delete_update(&ifp); /* If VRF, delete the VRF structure itself. */ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) diff --git a/zebra/interface.c b/zebra/interface.c index 69d611e583..a70326ebb3 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -806,9 +806,10 @@ static void if_delete_connected(struct interface *ifp) } /* Handle an interface delete event */ -void if_delete_update(struct interface *ifp) +void if_delete_update(struct interface **pifp) { struct zebra_if *zif; + struct interface *ifp = *pifp; if (if_is_up(ifp)) { flog_err( @@ -871,7 +872,7 @@ void if_delete_update(struct interface *ifp) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("interface %s is being deleted from the system", ifp->name); - if_delete(&ifp); + if_delete(pifp); } } diff --git a/zebra/interface.h b/zebra/interface.h index 4b06603e7f..c6930ce816 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -492,7 +492,7 @@ extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp, struct in6_addr *address, int add); extern void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp); -extern void if_delete_update(struct interface *ifp); +extern void if_delete_update(struct interface **ifp); extern void if_add_update(struct interface *ifp); extern void if_up(struct interface *ifp, bool install_connected); extern void if_down(struct interface *); diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 9b6aaf1d85..a895ed9410 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -136,7 +136,7 @@ static int if_ioctl_ipv6(unsigned long request, caddr_t buffer) void if_get_metric(struct interface *ifp) { #ifdef SIOCGIFMETRIC - struct ifreq ifreq; + struct ifreq ifreq = {}; ifreq_set_name(&ifreq, ifp); @@ -153,7 +153,7 @@ void if_get_metric(struct interface *ifp) /* get interface MTU */ void if_get_mtu(struct interface *ifp) { - struct ifreq ifreq; + struct ifreq ifreq = {}; ifreq_set_name(&ifreq, ifp); @@ -410,8 +410,8 @@ int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx) void if_get_flags(struct interface *ifp) { int ret; - struct ifreq ifreqflags; - struct ifreq ifreqdata; + struct ifreq ifreqflags = {}; + struct ifreq ifreqdata = {}; ifreq_set_name(&ifreqflags, ifp); ifreq_set_name(&ifreqdata, ifp); diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 0dd76e3253..35f3274c65 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -1016,6 +1016,18 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), return err; } + /* + * What is the right thing to do? The kernel + * is telling us that the dump request was interrupted + * and we more than likely are out of luck and have + * missed data from the kernel. At this point in time + * lets just note that this is happening. + */ + if (h->nlmsg_flags & NLM_F_DUMP_INTR) + flog_err( + EC_ZEBRA_NETLINK_BAD_SEQUENCE, + "netlink recvmsg: The Dump request was interrupted"); + /* OK we got netlink message. */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 6583af0a54..d6ca92f54e 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -159,6 +159,9 @@ const struct message rtm_type_str[] = {{RTM_ADD, "RTM_ADD"}, #ifdef RTM_IFANNOUNCE {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"}, #endif /* RTM_IFANNOUNCE */ +#ifdef RTM_IEEE80211 + {RTM_IEEE80211, "RTM_IEEE80211"}, +#endif {0}}; static const struct message rtm_flag_str[] = {{RTF_UP, "UP"}, @@ -450,12 +453,13 @@ static int ifan_read(struct if_announcemsghdr *ifan) if_get_metric(ifp); if_add_update(ifp); } else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE) - if_delete_update(ifp); - - if_get_flags(ifp); - if_get_mtu(ifp); - if_get_metric(ifp); + if_delete_update(&ifp); + if (ifp) { + if_get_flags(ifp); + if_get_mtu(ifp); + if_get_metric(ifp); + } if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("%s: interface %s index %d", __func__, ifan->ifan_name, ifan->ifan_index); @@ -722,10 +726,10 @@ int ifm_read(struct if_msghdr *ifm) * will still behave correctly if run on a platform * without */ - if_delete_update(ifp); + if_delete_update(&ifp); } #endif /* RTM_IFANNOUNCE */ - if (if_is_up(ifp)) { + if (ifp && if_is_up(ifp)) { #if defined(__bsdi__) if_kvm_get_mtu(ifp); #else @@ -735,14 +739,16 @@ int ifm_read(struct if_msghdr *ifm) } } + if (ifp) { #ifdef HAVE_NET_RT_IFLIST - ifp->stats = ifm->ifm_data; + ifp->stats = ifm->ifm_data; #endif /* HAVE_NET_RT_IFLIST */ - ifp->speed = ifm->ifm_data.ifi_baudrate / 1000000; + ifp->speed = ifm->ifm_data.ifi_baudrate / 1000000; - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: interface %s index %d", __func__, ifp->name, - ifp->ifindex); + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: interface %s index %d", __func__, + ifp->name, ifp->ifindex); + } return 0; } @@ -1405,7 +1411,10 @@ static void kernel_read(struct thread *thread) #endif /* RTM_IFANNOUNCE */ default: if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Unprocessed RTM_type: %d", rtm->rtm_type); + zlog_debug( + "Unprocessed RTM_type: %s(%d)", + lookup_msg(rtm_type_str, rtm->rtm_type, NULL), + rtm->rtm_type); break; } } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index e94aee5c1a..fd475e4cee 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1215,7 +1215,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) p.family); return; } - rnh = zebra_add_rnh(&p, zvrf_id(zvrf), &exist); + rnh = zebra_add_rnh(&p, zvrf_id(zvrf), safi, &exist); if (!rnh) return; diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 1a1cbaa948..46d789bc34 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -2479,9 +2479,13 @@ void zebra_evpn_mac_gw_macip_add(struct interface *ifp, if (zvrf && zvrf->zns) local_ns_id = zvrf->zns->ns_id; - mac = zebra_evpn_mac_lookup(zevpn, macaddr); - if (!mac) - mac = zebra_evpn_mac_add(zevpn, macaddr); + if (!*macp) { + mac = zebra_evpn_mac_lookup(zevpn, macaddr); + if (!mac) + mac = zebra_evpn_mac_add(zevpn, macaddr); + *macp = mac; + } else + mac = *macp; /* Set "local" forwarding info. */ zebra_evpn_mac_clear_fwd_info(mac); @@ -2494,8 +2498,6 @@ void zebra_evpn_mac_gw_macip_add(struct interface *ifp, mac->fwd_info.local.ifindex = ifp->ifindex; mac->fwd_info.local.ns_id = local_ns_id; mac->fwd_info.local.vid = vlan_id; - - *macp = mac; } void zebra_evpn_mac_svi_del(struct interface *ifp, struct zebra_evpn *zevpn) @@ -2548,7 +2550,6 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn) ? true : false; - mac = NULL; zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0, false); new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index 6a8ec1d2e1..b727ac1f98 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -124,8 +124,8 @@ struct zebra_mac { /* List of neigh associated with this mac */ struct list *neigh_list; - /* list of hosts pointing to this remote RMAC */ - struct host_rb_tree_entry host_rb; + /* List of nexthop associated with this RMAC */ + struct list *nh_list; /* Duplicate mac detection */ uint32_t dad_count; diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 7cb1906895..af6046c9ad 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -179,7 +179,7 @@ static int zebra_ns_delete(char *name) } UNSET_FLAG(ifp->flags, IFF_UP); - if_delete_update(ifp); + if_delete_update(&ifp); } ns = (struct ns *)vrf->ns_ctxt; diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 4d5336120d..7934a9d206 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -132,13 +132,13 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh) route_unlock_node(rn); } -struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, bool *exists) +struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, safi_t safi, + bool *exists) { struct route_table *table; struct route_node *rn; struct rnh *rnh = NULL; afi_t afi = family2afi(p->family); - safi_t safi = SAFI_UNICAST; if (IS_ZEBRA_DEBUG_NHT) { struct vrf *vrf = vrf_lookup_by_id(vrfid); @@ -345,7 +345,7 @@ void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw, return; addr2hostprefix(pw->af, &pw->nexthop, &nh); - rnh = zebra_add_rnh(&nh, vrf_id, &exists); + rnh = zebra_add_rnh(&nh, vrf_id, SAFI_UNICAST, &exists); if (!rnh) return; @@ -768,7 +768,7 @@ static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi, * of a particular VRF and address-family or a specific prefix. */ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force, - struct prefix *p, safi_t safi) + const struct prefix *p, safi_t safi) { struct route_table *rnh_table; struct route_node *nrn; @@ -802,13 +802,13 @@ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force, } } -void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty, - struct prefix *p) +void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi, + struct vty *vty, const struct prefix *p) { struct route_table *table; struct route_node *rn; - table = get_rnh_table(vrfid, afi, SAFI_UNICAST); + table = get_rnh_table(vrfid, afi, safi); if (!table) { if (IS_ZEBRA_DEBUG_NHT) zlog_debug("print_rnhs: rnh table not found"); @@ -1337,7 +1337,7 @@ static void print_rnh(struct route_node *rn, struct vty *vty) vty_out(vty, "\n"); } -static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, +static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, safi_t safi, struct zserv *client) { struct route_table *ntable; @@ -1352,7 +1352,7 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, zebra_route_string(client->proto), afi2str(afi)); } - ntable = get_rnh_table(vrf_id, afi, SAFI_UNICAST); + ntable = get_rnh_table(vrf_id, afi, safi); if (!ntable) { zlog_debug("cleanup_rnh_client: rnh table not found"); return -1; @@ -1377,9 +1377,14 @@ static int zebra_client_cleanup_rnh(struct zserv *client) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { zvrf = vrf->info; if (zvrf) { - zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client); + zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, + SAFI_UNICAST, client); + zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, + SAFI_MULTICAST, client); + zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6, + SAFI_UNICAST, client); zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6, - client); + SAFI_MULTICAST, client); } } diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 27c016ebe6..70eda725c4 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -31,7 +31,7 @@ extern "C" { extern void zebra_rnh_init(void); -extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, +extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, safi_t safi, bool *exists); extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, safi_t safi); @@ -44,9 +44,9 @@ extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *, bool *); extern void zebra_deregister_rnh_pseudowire(vrf_id_t, struct zebra_pw *); extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client); extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force, - struct prefix *p, safi_t safi); -extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty, - struct prefix *p); + const struct prefix *p, safi_t safi); +extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi, + struct vty *vty, const struct prefix *p); extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 32bbfd6654..22c65e3c0c 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1361,7 +1361,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, DEFPY (show_ip_nht, show_ip_nht_cmd, - "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name [<A.B.C.D|X:X::X:X>$addr]|vrf all$vrf_all]", + "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name [<A.B.C.D|X:X::X:X>$addr]|vrf all$vrf_all] [mrib$mrib]", SHOW_STR IP_STR IP6_STR @@ -1372,11 +1372,13 @@ DEFPY (show_ip_nht, VRF_CMD_HELP_STR "IPv4 Address\n" "IPv6 Address\n" - VRF_ALL_CMD_HELP_STR) + VRF_ALL_CMD_HELP_STR + "Show Multicast (MRIB) NHT state\n") { afi_t afi = ipv4 ? AFI_IP : AFI_IP6; vrf_id_t vrf_id = VRF_DEFAULT; struct prefix prefix, *p = NULL; + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; if (vrf_all) { struct vrf *vrf; @@ -1385,8 +1387,8 @@ DEFPY (show_ip_nht, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf)); - zebra_print_rnh_table(zvrf_id(zvrf), afi, vty, - NULL); + zebra_print_rnh_table(zvrf_id(zvrf), afi, safi, + vty, NULL); } return CMD_SUCCESS; } @@ -1400,7 +1402,7 @@ DEFPY (show_ip_nht, return CMD_WARNING; } - zebra_print_rnh_table(vrf_id, afi, vty, p); + zebra_print_rnh_table(vrf_id, afi, safi, vty, p); return CMD_SUCCESS; } diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 6a3b1bfbe3..13e1f63457 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -62,6 +62,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash"); DEFINE_MTYPE_STATIC(ZEBRA, L3VNI_MAC, "EVPN L3VNI MAC"); DEFINE_MTYPE_STATIC(ZEBRA, L3NEIGH, "EVPN Neighbor"); DEFINE_MTYPE_STATIC(ZEBRA, ZVXLAN_SG, "zebra VxLAN multicast group"); +DEFINE_MTYPE_STATIC(ZEBRA, EVPN_VTEP, "zebra VxLAN VTEP IP"); DEFINE_HOOK(zebra_rmac_update, (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete, @@ -198,6 +199,37 @@ static uint32_t rb_host_count(struct host_rb_tree_entry *hrbe) return count; } +static int l3vni_rmac_nh_list_cmp(void *p1, void *p2) +{ + const struct ipaddr *vtep_ip1 = p1; + const struct ipaddr *vtep_ip2 = p2; + + return !ipaddr_cmp(vtep_ip1, vtep_ip2); +} + +static void l3vni_rmac_nh_free(struct ipaddr *vtep_ip) +{ + XFREE(MTYPE_EVPN_VTEP, vtep_ip); +} + +static void l3vni_rmac_nh_list_nh_delete(struct zebra_l3vni *zl3vni, + struct zebra_mac *zrmac, + struct ipaddr *vtep_ip) +{ + struct listnode *node = NULL, *nnode = NULL; + struct ipaddr *vtep = NULL; + + for (ALL_LIST_ELEMENTS(zrmac->nh_list, node, nnode, vtep)) { + if (ipaddr_cmp(vtep, vtep_ip) == 0) + break; + } + + if (node) { + l3vni_rmac_nh_free(vtep); + list_delete_node(zrmac->nh_list, node); + } +} + /* * Print neighbors for all EVPN. */ @@ -366,35 +398,25 @@ static void zl3vni_print_nh(struct zebra_neigh *n, struct vty *vty, static void zl3vni_print_rmac(struct zebra_mac *zrmac, struct vty *vty, json_object *json) { - char buf1[ETHER_ADDR_STRLEN]; - char buf2[PREFIX_STRLEN]; - json_object *json_hosts = NULL; - struct host_rb_entry *hle; + struct listnode *node = NULL; + struct ipaddr *vtep = NULL; + json_object *json_nhs = NULL; if (!json) { - vty_out(vty, "MAC: %s\n", - prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1))); + vty_out(vty, "MAC: %pEA\n", &zrmac->macaddr); vty_out(vty, " Remote VTEP: %pI4\n", &zrmac->fwd_info.r_vtep_ip); - vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb)); - vty_out(vty, " Prefixes:\n"); - RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb) - vty_out(vty, " %pFX\n", &hle->p); } else { - json_hosts = json_object_new_array(); - json_object_string_add( - json, "routerMac", - prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1))); + json_nhs = json_object_new_array(); + json_object_string_addf(json, "routerMac", "%pEA", + &zrmac->macaddr); json_object_string_addf(json, "vtepIp", "%pI4", &zrmac->fwd_info.r_vtep_ip); - json_object_int_add(json, "refCount", - rb_host_count(&zrmac->host_rb)); - RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb) - json_object_array_add( - json_hosts, - json_object_new_string(prefix2str( - &hle->p, buf2, sizeof(buf2)))); - json_object_object_add(json, "prefixList", json_hosts); + for (ALL_LIST_ELEMENTS_RO(zrmac->nh_list, node, vtep)) { + json_object_array_add(json_nhs, json_object_new_stringf( + "%pIA", vtep)); + } + json_object_object_add(json, "nexthops", json_nhs); } } @@ -1169,7 +1191,9 @@ static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni, zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc); assert(zrmac); - RB_INIT(host_rb_tree_entry, &zrmac->host_rb); + zrmac->nh_list = list_new(); + zrmac->nh_list->cmp = (int (*)(void *, void *))l3vni_rmac_nh_list_cmp; + zrmac->nh_list->del = (void (*)(void *))l3vni_rmac_nh_free; SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE); SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC); @@ -1183,14 +1207,9 @@ static struct zebra_mac *zl3vni_rmac_add(struct zebra_l3vni *zl3vni, static int zl3vni_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac) { struct zebra_mac *tmp_rmac; - struct host_rb_entry *hle; - while (!RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) { - hle = RB_ROOT(host_rb_tree_entry, &zrmac->host_rb); - - RB_REMOVE(host_rb_tree_entry, &zrmac->host_rb, hle); - XFREE(MTYPE_HOST_PREFIX, hle); - } + /* free the list of nh list*/ + list_delete(&zrmac->nh_list); tmp_rmac = hash_release(zl3vni->rmac_table, zrmac); XFREE(MTYPE_L3VNI_MAC, tmp_rmac); @@ -1291,10 +1310,10 @@ static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni, /* handle rmac add */ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, const struct ethaddr *rmac, - const struct ipaddr *vtep_ip, - const struct prefix *host_prefix) + const struct ipaddr *vtep_ip) { struct zebra_mac *zrmac = NULL; + struct ipaddr *vtep = NULL; zrmac = zl3vni_rmac_lookup(zl3vni, rmac); if (!zrmac) { @@ -1303,13 +1322,18 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, zrmac = zl3vni_rmac_add(zl3vni, rmac); if (!zrmac) { zlog_debug( - "Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA, prefix %pFX", - rmac, zl3vni->vni, vtep_ip, host_prefix); + "Failed to add RMAC %pEA L3VNI %u Remote VTEP %pIA", + rmac, zl3vni->vni, vtep_ip); return -1; } memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info)); zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; + vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr)); + memcpy(vtep, vtep_ip, sizeof(struct ipaddr)); + if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep)) + XFREE(MTYPE_EVPN_VTEP, vtep); + /* Send RMAC for FPM processing */ hook_call(zebra_rmac_update, zrmac, zl3vni, false, "new RMAC added"); @@ -1320,18 +1344,21 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, &vtep_ip->ipaddr_v4)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA, prefix %pFX", + "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA", zl3vni->vni, &zrmac->fwd_info.r_vtep_ip, - vtep_ip, rmac, host_prefix); + vtep_ip, rmac); zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; + vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr)); + memcpy(vtep, vtep_ip, sizeof(struct ipaddr)); + if (!listnode_add_sort_nodup(zrmac->nh_list, (void *)vtep)) + XFREE(MTYPE_EVPN_VTEP, vtep); + /* install rmac in kernel */ zl3vni_rmac_install(zl3vni, zrmac); } - rb_find_or_add_host(&zrmac->host_rb, host_prefix); - return 0; } @@ -1339,20 +1366,59 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, /* handle rmac delete */ static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac, - struct prefix *host_prefix) + struct ipaddr *vtep_ip) { - rb_delete_host(&zrmac->host_rb, host_prefix); + struct ipaddr ipv4_vtep; - if (RB_EMPTY(host_rb_tree_entry, &zrmac->host_rb)) { - /* uninstall from kernel */ - zl3vni_rmac_uninstall(zl3vni, zrmac); + if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) { + memset(&ipv4_vtep, 0, sizeof(struct ipaddr)); + ipv4_vtep.ipa_type = IPADDR_V4; + if (vtep_ip->ipa_type == IPADDR_V6) + ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, + &ipv4_vtep.ipaddr_v4); + else + memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4, + sizeof(struct in_addr)); - /* Send RMAC for FPM processing */ - hook_call(zebra_rmac_update, zrmac, zl3vni, true, - "RMAC deleted"); + /* remove nh from rmac's list */ + l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep); + /* delete nh is same as current selected, fall back to + * one present in the list + */ + if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip, + &ipv4_vtep.ipaddr_v4) && + listcount(zrmac->nh_list)) { + struct ipaddr *vtep; + + vtep = listgetdata(listhead(zrmac->nh_list)); + zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA", + zl3vni->vni, &ipv4_vtep, + &zrmac->fwd_info.r_vtep_ip, + &zrmac->macaddr); + + /* install rmac in kernel */ + zl3vni_rmac_install(zl3vni, zrmac); + } + + if (!listcount(zrmac->nh_list)) { + /* uninstall from kernel */ + zl3vni_rmac_uninstall(zl3vni, zrmac); - /* del the rmac entry */ - zl3vni_rmac_del(zl3vni, zrmac); + /* Send RMAC for FPM processing */ + hook_call(zebra_rmac_update, zrmac, zl3vni, true, + "RMAC deleted"); + + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "L3VNI %u RMAC %pEA vtep_ip %pIA delete", + zl3vni->vni, &zrmac->macaddr, vtep_ip); + + /* del the rmac entry */ + zl3vni_rmac_del(zl3vni, zrmac); + } } } @@ -2235,7 +2301,7 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, * add the rmac - remote rmac to be installed is against the ipv4 * nexthop address */ - zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix); + zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep); } /* handle evpn vrf route delete */ @@ -2262,8 +2328,7 @@ void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id, /* delete the rmac entry */ if (zrmac) - zl3vni_remote_rmac_del(zl3vni, zrmac, host_prefix); - + zl3vni_remote_rmac_del(zl3vni, zrmac, vtep_ip); } void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni, @@ -2297,7 +2362,7 @@ void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni, vty_out(vty, "{}\n"); else vty_out(vty, - "%% Requested RMAC doesn't exist in L3-VNI %u", + "%% Requested RMAC doesn't exist in L3-VNI %u\n", l3vni); return; } |
