]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_zebra.c
Merge pull request #5430 from taruta811/build-docker-centos
[mirror_frr.git] / pimd / pim_zebra.c
index b0db23f54ac0ec3428e0c5e78eca1b84a6df6773..b999188a9b804f178ed135c7f95329ab901a6064 100644 (file)
 #include "pim_nht.h"
 #include "pim_ssm.h"
 #include "pim_vxlan.h"
+#include "pim_mlag.h"
 
 #undef PIM_DEBUG_IFADDR_DUMP
 #define PIM_DEBUG_IFADDR_DUMP
 
-static struct zclient *zclient = NULL;
+struct zclient *zclient;
 
 
 /* Router-id update message from zebra. */
@@ -63,218 +64,6 @@ static int pim_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
        return 0;
 }
 
-static int pim_zebra_if_add(ZAPI_CALLBACK_ARGS)
-{
-       struct interface *ifp;
-       struct pim_instance *pim;
-
-       /*
-         zebra api adds/dels interfaces using the same call
-         interface_add_read below, see comments in lib/zclient.c
-       */
-       ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-       if (!ifp)
-               return 0;
-
-       pim = pim_get_pim_instance(vrf_id);
-       if (PIM_DEBUG_ZEBRA) {
-               zlog_debug(
-                       "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
-                       (long)ifp->flags, ifp->metric, ifp->mtu,
-                       if_is_operative(ifp));
-       }
-
-       if (if_is_operative(ifp)) {
-               struct pim_interface *pim_ifp;
-
-               pim_ifp = ifp->info;
-               /*
-                * If we have a pim_ifp already and this is an if_add
-                * that means that we probably have a vrf move event
-                * If that is the case, set the proper vrfness.
-                */
-               if (pim_ifp)
-                       pim_ifp->pim = pim;
-               pim_if_addr_add_all(ifp);
-       }
-
-       /*
-        * If we are a vrf device that is up, open up the pim_socket for
-        * listening
-        * to incoming pim messages irrelevant if the user has configured us
-        * for pim or not.
-        */
-       if (pim_if_is_vrf_device(ifp)) {
-               struct pim_interface *pim_ifp;
-
-               if (!ifp->info) {
-                       pim_ifp = pim_if_new(ifp, false, false, false,
-                                       false /*vxlan_term*/);
-                       ifp->info = pim_ifp;
-               }
-
-               pim_sock_add(ifp);
-       }
-
-       if (!strncmp(ifp->name, PIM_VXLAN_TERM_DEV_NAME,
-                               sizeof(PIM_VXLAN_TERM_DEV_NAME)))
-               pim_vxlan_add_term_dev(pim, ifp);
-
-       return 0;
-}
-
-static int pim_zebra_if_del(ZAPI_CALLBACK_ARGS)
-{
-       struct interface *ifp;
-       struct pim_instance *pim;
-
-       /*
-         zebra api adds/dels interfaces using the same call
-         interface_add_read below, see comments in lib/zclient.c
-
-         comments in lib/zclient.c seem to indicate that calling
-         zebra_interface_add_read is the correct call, but that
-         results in an attemted out of bounds read which causes
-         pimd to assert. Other clients use zebra_interface_state_read
-         and it appears to work just fine.
-       */
-       ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-       if (!ifp)
-               return 0;
-
-       if (PIM_DEBUG_ZEBRA) {
-               zlog_debug(
-                       "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
-                       (long)ifp->flags, ifp->metric, ifp->mtu,
-                       if_is_operative(ifp));
-       }
-
-       if (!if_is_operative(ifp))
-               pim_if_addr_del_all(ifp);
-
-       if_set_index(ifp, IFINDEX_INTERNAL);
-
-       pim = pim_get_pim_instance(vrf_id);
-       if (pim && pim->vxlan.term_if == ifp)
-               pim_vxlan_del_term_dev(pim);
-
-       return 0;
-}
-
-static int pim_zebra_if_state_up(ZAPI_CALLBACK_ARGS)
-{
-       struct pim_instance *pim;
-       struct interface *ifp;
-       uint32_t table_id;
-
-       /*
-         zebra api notifies interface up/down events by using the same call
-         zebra_interface_state_read below, see comments in lib/zclient.c
-       */
-       ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-       if (!ifp)
-               return 0;
-
-       if (PIM_DEBUG_ZEBRA) {
-               zlog_debug(
-                       "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
-                       (long)ifp->flags, ifp->metric, ifp->mtu,
-                       if_is_operative(ifp));
-       }
-
-       pim = pim_get_pim_instance(vrf_id);
-       if (if_is_operative(ifp)) {
-               struct pim_interface *pim_ifp;
-
-               pim_ifp = ifp->info;
-               /*
-                * If we have a pim_ifp already and this is an if_add
-                * that means that we probably have a vrf move event
-                * If that is the case, set the proper vrfness.
-                */
-               if (pim_ifp)
-                       pim_ifp->pim = pim;
-
-               /*
-                 pim_if_addr_add_all() suffices for bringing up both IGMP and
-                 PIM
-               */
-               pim_if_addr_add_all(ifp);
-       }
-
-       /*
-        * If we have a pimreg device callback and it's for a specific
-        * table set the master appropriately
-        */
-       if (sscanf(ifp->name, "pimreg%" SCNu32, &table_id) == 1) {
-               struct vrf *vrf;
-               RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-                       if ((table_id == vrf->data.l.table_id)
-                           && (ifp->vrf_id != vrf->vrf_id)) {
-                               struct interface *master = if_lookup_by_name(
-                                       vrf->name, vrf->vrf_id);
-
-                               if (!master) {
-                                       zlog_debug(
-                                               "%s: Unable to find Master interface for %s",
-                                               __PRETTY_FUNCTION__, vrf->name);
-                                       return 0;
-                               }
-                               zclient_interface_set_master(zclient, master,
-                                                            ifp);
-                       }
-               }
-       }
-       return 0;
-}
-
-static int pim_zebra_if_state_down(ZAPI_CALLBACK_ARGS)
-{
-       struct interface *ifp;
-
-       /*
-         zebra api notifies interface up/down events by using the same call
-         zebra_interface_state_read below, see comments in lib/zclient.c
-       */
-       ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-       if (!ifp)
-               return 0;
-
-       if (PIM_DEBUG_ZEBRA) {
-               zlog_debug(
-                       "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
-                       __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
-                       (long)ifp->flags, ifp->metric, ifp->mtu,
-                       if_is_operative(ifp));
-       }
-
-       if (!if_is_operative(ifp)) {
-               pim_ifchannel_delete_all(ifp);
-               /*
-                 pim_if_addr_del_all() suffices for shutting down IGMP,
-                 but not for shutting down PIM
-               */
-               pim_if_addr_del_all(ifp);
-
-               /*
-                 pim_sock_delete() closes the socket, stops read and timer
-                 threads,
-                 and kills all neighbors.
-               */
-               if (ifp->info) {
-                       pim_sock_delete(ifp, "link down");
-               }
-       }
-
-       if (ifp->info)
-               pim_if_del_vif(ifp);
-
-       return 0;
-}
-
 static int pim_zebra_interface_vrf_update(ZAPI_CALLBACK_ARGS)
 {
        struct interface *ifp;
@@ -445,7 +234,7 @@ static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
                pim_i_am_rp_re_evaluate(pim);
        }
 
-       connected_free(c);
+       connected_free(&c);
        return 0;
 }
 
@@ -793,16 +582,15 @@ void pim_zebra_init(void)
        zclient->zebra_capabilities = pim_zebra_capabilities;
        zclient->zebra_connected = pim_zebra_connected;
        zclient->router_id_update = pim_router_id_update_zebra;
-       zclient->interface_add = pim_zebra_if_add;
-       zclient->interface_delete = pim_zebra_if_del;
-       zclient->interface_up = pim_zebra_if_state_up;
-       zclient->interface_down = pim_zebra_if_state_down;
        zclient->interface_address_add = pim_zebra_if_address_add;
        zclient->interface_address_delete = pim_zebra_if_address_del;
        zclient->interface_vrf_update = pim_zebra_interface_vrf_update;
        zclient->nexthop_update = pim_parse_nexthop_update;
        zclient->vxlan_sg_add = pim_zebra_vxlan_sg_proc;
        zclient->vxlan_sg_del = pim_zebra_vxlan_sg_proc;
+       zclient->mlag_process_up = pim_zebra_mlag_process_up;
+       zclient->mlag_process_down = pim_zebra_mlag_process_down;
+       zclient->mlag_handle_msg = pim_zebra_mlag_handle_msg;
 
        zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
        if (PIM_DEBUG_PIM_TRACE) {
@@ -1071,27 +859,24 @@ void igmp_source_forward_start(struct pim_instance *pim,
                }
        }
 
-       result = pim_channel_add_oif(source->source_channel_oil,
-                                    group->group_igmp_sock->interface,
-                                    PIM_OIF_FLAG_PROTO_IGMP);
-       if (result) {
-               if (PIM_DEBUG_MROUTE) {
-                       zlog_warn("%s: add_oif() failed with return=%d",
-                                 __func__, result);
+       if (PIM_I_am_DR(pim_oif)) {
+               result = pim_channel_add_oif(source->source_channel_oil,
+                                            group->group_igmp_sock->interface,
+                                            PIM_OIF_FLAG_PROTO_IGMP);
+               if (result) {
+                       if (PIM_DEBUG_MROUTE) {
+                               zlog_warn("%s: add_oif() failed with return=%d",
+                                         __func__, result);
+                       }
+                       return;
                }
-               return;
-       }
-
-       if (!(PIM_I_am_DR(pim_oif))) {
+       } else {
                if (PIM_DEBUG_IGMP_TRACE)
                        zlog_debug("%s: %s was received on %s interface but we are not DR for that interface",
                                   __PRETTY_FUNCTION__,
                                   pim_str_sg_dump(&sg),
                                   group->group_igmp_sock->interface->name);
 
-               pim_channel_del_oif(source->source_channel_oil,
-                                   group->group_igmp_sock->interface,
-                                   PIM_OIF_FLAG_PROTO_IGMP);
                return;
        }
        /*
@@ -1180,12 +965,6 @@ void pim_forward_start(struct pim_ifchannel *ch)
 {
        struct pim_upstream *up = ch->upstream;
        uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
-       int input_iface_vif_index = 0;
-       struct pim_instance *pim;
-       struct pim_interface *pim_ifp;
-
-       pim_ifp = ch->interface->info;
-       pim = pim_ifp->pim;
 
        if (PIM_DEBUG_PIM_TRACE) {
                char source_str[INET_ADDRSTRLEN];
@@ -1203,55 +982,6 @@ void pim_forward_start(struct pim_ifchannel *ch)
                           inet_ntoa(up->upstream_addr));
        }
 
-       /* Resolve IIF for upstream as mroute_del sets mfcc_parent to MAXVIFS,
-          as part of mroute_del called by pim_forward_stop.
-       */
-       if ((up->upstream_addr.s_addr != INADDR_ANY) && (!up->channel_oil)) {
-               struct prefix src, grp;
-
-               grp.family = AF_INET;
-               grp.prefixlen = IPV4_MAX_BITLEN;
-               grp.u.prefix4 = up->sg.grp;
-               src.family = AF_INET;
-               src.prefixlen = IPV4_MAX_BITLEN;
-               src.u.prefix4 = up->sg.src;
-
-               if (pim_ecmp_nexthop_lookup(pim, &up->rpf.source_nexthop, &src,
-                                           &grp, 0))
-                       input_iface_vif_index = pim_if_find_vifindex_by_ifindex(
-                               pim, up->rpf.source_nexthop.interface->ifindex);
-
-               if (input_iface_vif_index < 1) {
-                       if (PIM_DEBUG_PIM_TRACE) {
-                               char source_str[INET_ADDRSTRLEN];
-                               pim_inet4_dump("<source?>", up->sg.src,
-                                              source_str, sizeof(source_str));
-                               zlog_debug(
-                                       "%s %s: could not find input interface for source %s",
-                                       __FILE__, __PRETTY_FUNCTION__,
-                                       source_str);
-                       }
-                       pim_channel_oil_change_iif(pim, up->channel_oil,
-                                                  MAXVIFS,
-                                                  __PRETTY_FUNCTION__);
-               }
-
-               else
-                       pim_channel_oil_change_iif(pim, up->channel_oil,
-                                                  input_iface_vif_index,
-                                                  __PRETTY_FUNCTION__);
-
-               if (PIM_DEBUG_TRACE) {
-                       struct interface *in_intf = pim_if_find_by_vif_index(
-                               pim, input_iface_vif_index);
-                       zlog_debug(
-                               "%s: Update channel_oil IIF %s VIFI %d entry %s ",
-                               __PRETTY_FUNCTION__,
-                               in_intf ? in_intf->name : "Unknown",
-                               input_iface_vif_index, up->sg_str);
-               }
-       }
-
        if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
                mask = PIM_OIF_FLAG_PROTO_IGMP;
 
@@ -1301,3 +1031,9 @@ struct zclient *pim_zebra_zclient_get(void)
        else
                return NULL;
 }
+
+void pim_zebra_interface_set_master(struct interface *vrf,
+                                   struct interface *ifp)
+{
+       zclient_interface_set_master(zclient, vrf, ifp);
+}