]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #10366 from AbhishekNR/mld_cli
authorDavid Lamparter <equinox@opensourcerouting.org>
Mon, 28 Mar 2022 07:18:36 +0000 (09:18 +0200)
committerGitHub <noreply@github.com>
Mon, 28 Mar 2022 07:18:36 +0000 (09:18 +0200)
1  2 
pimd/pim_iface.c
pimd/pim_nb_config.c

diff --combined pimd/pim_iface.c
index 98fa4c4882519a8cdac11ff3edcfd8bf435cedae,168bf6ea6a9769217b6faf32d24d6bcd2ae9ef5f..8e0e418a9949ffec4a8ce646083df018930724e0
@@@ -53,8 -53,8 +53,8 @@@
  #if PIM_IPV == 4
  static void pim_if_igmp_join_del_all(struct interface *ifp);
  static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
 -                        struct in_addr group_addr,
 -                        struct in_addr source_addr);
 +                        struct in_addr group_addr, struct in_addr source_addr,
 +                        struct pim_interface *pim_ifp);
  #endif
  
  void pim_if_init(struct pim_instance *pim)
@@@ -127,6 -127,7 +127,6 @@@ struct pim_interface *pim_if_new(struc
        pim_ifp->pim = ifp->vrf->info;
        pim_ifp->mroute_vif_index = -1;
  
 -#if PIM_IPV == 4
        pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
        pim_ifp->gm_default_robustness_variable =
                IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
  
        if (pim)
                PIM_IF_DO_PIM(pim_ifp->options);
 +#if PIM_IPV == 4
        if (igmp)
                PIM_IF_DO_IGMP(pim_ifp->options);
  
        PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
 +#endif
  
        pim_ifp->gm_join_list = NULL;
        pim_ifp->pim_neighbor_list = NULL;
  
        ifp->info = pim_ifp;
  
 +#if PIM_IPV == 4
        pim_sock_reset(ifp);
 +#endif
  
        pim_if_add_vif(ifp, ispimreg, is_vxlan_term);
 -#endif
        pim_ifp->pim->mcast_if_count++;
  
        return pim_ifp;
@@@ -210,12 -208,9 +210,12 @@@ void pim_if_delete(struct interface *if
        if (pim_ifp->gm_join_list) {
                pim_if_igmp_join_del_all(ifp);
        }
 +#endif
  
        pim_ifchannel_delete_all(ifp);
 +#if PIM_IPV == 4
        igmp_sock_delete_all(ifp);
 +#endif
  
        pim_neighbor_delete_all(ifp, "Interface removed from configuration");
  
  
        XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
        XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
 -#endif
  
        ifp->info = NULL;
  }
@@@ -516,26 -512,6 +516,26 @@@ void pim_if_addr_add(struct connected *
                           CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
                                   ? "secondary"
                                   : "primary");
 +#if PIM_IPV != 4
 +      if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) ||
 +          IN6_IS_ADDR_LOOPBACK(&ifc->address->u.prefix6)) {
 +              if (IN6_IS_ADDR_UNSPECIFIED(&pim_ifp->ll_lowest))
 +                      pim_ifp->ll_lowest = ifc->address->u.prefix6;
 +              else if (IPV6_ADDR_CMP(&ifc->address->u.prefix6,
 +                                     &pim_ifp->ll_lowest) < 0)
 +                      pim_ifp->ll_lowest = ifc->address->u.prefix6;
 +
 +              if (IPV6_ADDR_CMP(&ifc->address->u.prefix6,
 +                                &pim_ifp->ll_highest) > 0)
 +                      pim_ifp->ll_highest = ifc->address->u.prefix6;
 +
 +              if (PIM_DEBUG_ZEBRA)
 +                      zlog_debug(
 +                              "%s: new link-local %pI6, lowest now %pI6, highest %pI6",
 +                              ifc->ifp->name, &ifc->address->u.prefix6,
 +                              &pim_ifp->ll_lowest, &pim_ifp->ll_highest);
 +      }
 +#endif
  
        detect_address_change(ifp, 0, __func__);
  
                                close(ij->sock_fd);
                                join_fd = igmp_join_sock(
                                        ifp->name, ifp->ifindex, ij->group_addr,
 -                                      ij->source_addr);
 +                                      ij->source_addr, pim_ifp);
                                if (join_fd < 0) {
                                        char group_str[INET_ADDRSTRLEN];
                                        char source_str[INET_ADDRSTRLEN];
@@@ -735,43 -711,6 +735,43 @@@ void pim_if_addr_del(struct connected *
                                   ? "secondary"
                                   : "primary");
  
 +#if PIM_IPV == 6
 +      struct pim_interface *pim_ifp = ifc->ifp->info;
 +
 +      if (pim_ifp &&
 +          (!IPV6_ADDR_CMP(&ifc->address->u.prefix6, &pim_ifp->ll_lowest) ||
 +           !IPV6_ADDR_CMP(&ifc->address->u.prefix6, &pim_ifp->ll_highest))) {
 +              struct listnode *cnode;
 +              struct connected *cc;
 +
 +              memset(&pim_ifp->ll_lowest, 0xff, sizeof(pim_ifp->ll_lowest));
 +              memset(&pim_ifp->ll_highest, 0, sizeof(pim_ifp->ll_highest));
 +
 +              for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected, cnode, cc)) {
 +                      if (!IN6_IS_ADDR_LINKLOCAL(&cc->address->u.prefix6) &&
 +                          !IN6_IS_ADDR_LOOPBACK(&cc->address->u.prefix6))
 +                              continue;
 +
 +                      if (IPV6_ADDR_CMP(&cc->address->u.prefix6,
 +                                        &pim_ifp->ll_lowest) < 0)
 +                              pim_ifp->ll_lowest = cc->address->u.prefix6;
 +                      if (IPV6_ADDR_CMP(&cc->address->u.prefix6,
 +                                        &pim_ifp->ll_highest) > 0)
 +                              pim_ifp->ll_highest = cc->address->u.prefix6;
 +              }
 +
 +              if (pim_ifp->ll_lowest.s6_addr[0] == 0xff)
 +                      memset(&pim_ifp->ll_lowest, 0,
 +                             sizeof(pim_ifp->ll_lowest));
 +
 +              if (PIM_DEBUG_ZEBRA)
 +                      zlog_debug(
 +                              "%s: removed link-local %pI6, lowest now %pI6, highest %pI6",
 +                              ifc->ifp->name, &ifc->address->u.prefix6,
 +                              &pim_ifp->ll_lowest, &pim_ifp->ll_highest);
 +      }
 +#endif
 +
        detect_address_change(ifp, force_prim_as_any, __func__);
  
        pim_if_addr_del_igmp(ifc);
@@@ -886,36 -825,17 +886,36 @@@ pim_addr pim_find_primary_addr(struct i
  {
        struct connected *ifc;
        struct listnode *node;
 -      int v4_addrs = 0;
 -      int v6_addrs = 0;
        struct pim_interface *pim_ifp = ifp->info;
  
 -      if (pim_ifp && !pim_addr_is_any(pim_ifp->update_source)) {
 +      if (pim_ifp && !pim_addr_is_any(pim_ifp->update_source))
                return pim_ifp->update_source;
 -      }
 +
 +#if PIM_IPV == 6
 +      if (pim_ifp)
 +              return pim_ifp->ll_highest;
 +
 +      pim_addr best_addr = PIMADDR_ANY;
  
        for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
                pim_addr addr;
  
 +              if (ifc->address->family != AF_INET6)
 +                      continue;
 +
 +              addr = pim_addr_from_prefix(ifc->address);
 +              if (!IN6_IS_ADDR_LINKLOCAL(&addr))
 +                      continue;
 +              if (pim_addr_cmp(addr, best_addr) > 0)
 +                      best_addr = addr;
 +      }
 +
 +      return best_addr;
 +#else
 +      int v4_addrs = 0;
 +      int v6_addrs = 0;
 +
 +      for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
                switch (ifc->address->family) {
                case AF_INET:
                        v4_addrs++;
                if (ifc->address->family != PIM_AF)
                        continue;
  
 -              addr = pim_addr_from_prefix(ifc->address);
 -
 -#if PIM_IPV == 6
 -              if (!IN6_IS_ADDR_LINKLOCAL(&addr))
 -                      continue;
 -#endif
 -              return addr;
 +              return pim_addr_from_prefix(ifc->address);
        }
  
 -#if PIM_IPV == 4
        /*
         * If we have no v4_addrs and v6 is configured
         * We probably are using unnumbered
                if (lo_ifp && (lo_ifp != ifp))
                        return pim_find_primary_addr(lo_ifp);
        }
 -#endif
        return PIMADDR_ANY;
 +#endif
  }
  
  static int pim_iface_next_vif_index(struct interface *ifp)
@@@ -1248,16 -1175,12 +1248,16 @@@ static struct gm_join *igmp_join_find(s
  }
  
  static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
 -                        struct in_addr group_addr, struct in_addr source_addr)
 +                        struct in_addr group_addr, struct in_addr source_addr,
 +                        struct pim_interface *pim_ifp)
  {
        int join_fd;
  
 +      pim_ifp->igmp_ifstat_joins_sent++;
 +
        join_fd = pim_socket_raw(IPPROTO_IGMP);
        if (join_fd < 0) {
 +              pim_ifp->igmp_ifstat_joins_failed++;
                return -1;
        }
  
                        __func__, join_fd, group_str, source_str, ifindex,
                        ifname, errno, safe_strerror(errno));
  
 +              pim_ifp->igmp_ifstat_joins_failed++;
 +
                close(join_fd);
                return -2;
        }
        return join_fd;
  }
  
+ #if PIM_IPV == 4
  static struct gm_join *igmp_join_new(struct interface *ifp,
                                     struct in_addr group_addr,
                                     struct in_addr source_addr)
        assert(pim_ifp);
  
        join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr,
 -                               source_addr);
 +                               source_addr, pim_ifp);
        if (join_fd < 0) {
                char group_str[INET_ADDRSTRLEN];
                char source_str[INET_ADDRSTRLEN];
  
        return ij;
  }
+ #endif /* PIM_IPV == 4 */
  
+ #if PIM_IPV == 4
  ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
                            struct in_addr source_addr)
  {
  
        return ferr_ok();
  }
+ #endif /* PIM_IPV == 4 */
  
  int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
                         struct in_addr source_addr)
@@@ -1628,6 -1552,7 +1631,6 @@@ static int pim_ifp_create(struct interf
                 */
                if (pim_ifp)
                        pim_ifp->pim = pim;
 -#if PIM_IPV == 4
                pim_if_addr_add_all(ifp);
  
                /*
                 * this is a no-op if it's already been done.
                 */
                pim_if_create_pimreg(pim);
 -#endif
        }
  
  #if PIM_IPV == 4
  
  static int pim_ifp_up(struct interface *ifp)
  {
 +      uint32_t table_id;
        struct pim_interface *pim_ifp;
        struct pim_instance *pim;
  
        if (pim_ifp)
                pim_ifp->pim = pim;
  
 -#if PIM_IPV == 4
 -      uint32_t table_id;
 -
        /*
          pim_if_addr_add_all() suffices for bringing up both IGMP and
          PIM
                        }
                }
        }
 -#endif
        return 0;
  }
  
@@@ -1740,6 -1669,7 +1743,6 @@@ static int pim_ifp_down(struct interfac
                        ifp->mtu, if_is_operative(ifp));
        }
  
 -#if PIM_IPV == 4
        if (!if_is_operative(ifp)) {
                pim_ifchannel_delete_all(ifp);
                /*
                */
                pim_if_addr_del_all(ifp);
  
 +#if PIM_IPV == 4
                /*
                  pim_sock_delete() closes the socket, stops read and timer
                  threads,
                if (ifp->info) {
                        pim_sock_delete(ifp, "link down");
                }
 +#endif
        }
  
        if (ifp->info) {
                pim_if_del_vif(ifp);
 +#if PIM_IPV == 4
                pim_ifstat_reset(ifp);
 -      }
  #endif
 +      }
  
        return 0;
  }
@@@ -1780,12 -1707,12 +1783,12 @@@ static int pim_ifp_destroy(struct inter
                        ifp->mtu, if_is_operative(ifp));
        }
  
 -#if PIM_IPV == 4
 -      struct pim_instance *pim;
 -
        if (!if_is_operative(ifp))
                pim_if_addr_del_all(ifp);
  
 +#if PIM_IPV == 4
 +      struct pim_instance *pim;
 +
        pim = ifp->vrf->info;
        if (pim && pim->vxlan.term_if == ifp)
                pim_vxlan_del_term_dev(pim);
diff --combined pimd/pim_nb_config.c
index 2fabee5dfd1a151a772699e751ef1c594bae5eae,f1b537060559178574b4f90fb222cbeaf8c9dd8c..7fe7c0395f0b9ad7451428a2bd899ce4c5372987
@@@ -348,6 -348,7 +348,7 @@@ static bool is_pim_interface(const stru
        return false;
  }
  
+ #if PIM_IPV == 4
  static int pim_cmd_igmp_start(struct interface *ifp)
  {
        struct pim_interface *pim_ifp;
  
        return NB_OK;
  }
+ #endif /* PIM_IPV == 4 */
  
  /*
   * CLI reconfiguration affects the interface level (struct pim_interface).
   * This function propagates the reconfiguration to every active socket
   * for that interface.
   */
+ #if PIM_IPV == 4
  static void igmp_sock_query_interval_reconfig(struct gm_sock *igmp)
  {
        struct interface *ifp;
         */
        igmp_startup_mode_on(igmp);
  }
+ #endif
  
  static void igmp_sock_query_reschedule(struct gm_sock *igmp)
  {
        }
  }
  
+ #if PIM_IPV == 4
  static void change_query_interval(struct pim_interface *pim_ifp,
                int query_interval)
  {
                igmp_sock_query_reschedule(igmp);
        }
  }
+ #endif
  
  static void change_query_max_response_time(struct pim_interface *pim_ifp,
                int query_max_response_time_dsec)
@@@ -930,7 -936,7 +936,7 @@@ int routing_control_plane_protocols_con
        struct vrf *vrf;
        struct pim_instance *pim;
        int result;
 -      struct ipaddr source_addr;
 +      pim_addr source_addr;
  
        switch (args->event) {
        case NB_EV_VALIDATE:
        case NB_EV_APPLY:
                vrf = nb_running_get_entry(args->dnode, NULL, true);
                pim = vrf->info;
 -              yang_dnode_get_ip(&source_addr, args->dnode, NULL);
 -              result = pim_ssmpingd_start(pim, source_addr.ip._v4_addr);
 +              yang_dnode_get_pimaddr(&source_addr, args->dnode,
 +                                     "./source-addr");
 +              result = pim_ssmpingd_start(pim, source_addr);
                if (result) {
 -                      char source_str[INET_ADDRSTRLEN];
 -
 -                      ipaddr2str(&source_addr, source_str,
 -                                      sizeof(source_str));
 -                      snprintf(args->errmsg, args->errmsg_len,
 -                               "%% Failure starting ssmpingd for source %s: %d",
 -                               source_str, result);
 +                      snprintf(
 +                              args->errmsg, args->errmsg_len,
 +                              "%% Failure starting ssmpingd for source %pPA: %d",
 +                              &source_addr, result);
                        return NB_ERR_INCONSISTENCY;
                }
        }
@@@ -961,7 -969,7 +967,7 @@@ int routing_control_plane_protocols_con
        struct vrf *vrf;
        struct pim_instance *pim;
        int result;
 -      struct ipaddr source_addr;
 +      pim_addr source_addr;
  
        switch (args->event) {
        case NB_EV_VALIDATE:
        case NB_EV_APPLY:
                vrf = nb_running_get_entry(args->dnode, NULL, true);
                pim = vrf->info;
 -              yang_dnode_get_ip(&source_addr, args->dnode, NULL);
 -              result = pim_ssmpingd_stop(pim, source_addr.ip._v4_addr);
 +              yang_dnode_get_pimaddr(&source_addr, args->dnode,
 +                                     "./source-addr");
 +              result = pim_ssmpingd_stop(pim, source_addr);
                if (result) {
 -                      char source_str[INET_ADDRSTRLEN];
 -
 -                      ipaddr2str(&source_addr, source_str,
 -                                 sizeof(source_str));
 -                      snprintf(args->errmsg, args->errmsg_len,
 -                               "%% Failure stopping ssmpingd for source %s: %d",
 -                                source_str, result);
 +                      snprintf(
 +                              args->errmsg, args->errmsg_len,
 +                              "%% Failure stopping ssmpingd for source %pPA: %d",
 +                              &source_addr, result);
                        return NB_ERR_INCONSISTENCY;
                }
  
@@@ -2550,6 -2560,7 +2556,7 @@@ int lib_interface_gmp_address_family_de
  int lib_interface_gmp_address_family_enable_modify(
        struct nb_cb_modify_args *args)
  {
+ #if PIM_IPV == 4
        struct interface *ifp;
        bool igmp_enable;
        struct pim_interface *pim_ifp;
                                pim_if_delete(ifp);
                }
        }
+ #else
+       /* TBD Depends on MLD data structure changes */
+ #endif /* PIM_IPV == 4 */
        return NB_OK;
  }
  
@@@ -2671,6 -2684,7 +2680,7 @@@ int lib_interface_gmp_address_family_ml
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
        case NB_EV_APPLY:
+               /* TBD depends on MLD data structure changes */
                break;
        }
  
@@@ -2697,6 -2711,7 +2707,7 @@@ int lib_interface_gmp_address_family_ml
  int lib_interface_gmp_address_family_query_interval_modify(
        struct nb_cb_modify_args *args)
  {
+ #if PIM_IPV == 4
        struct interface *ifp;
        int query_interval;
  
                query_interval = yang_dnode_get_uint16(args->dnode, NULL);
                change_query_interval(ifp->info, query_interval);
        }
+ #else
+       /* TBD Depends on MLD data structure changes */
+ #endif
        return NB_OK;
  }
  
@@@ -2802,6 -2819,7 +2815,7 @@@ int lib_interface_gmp_address_family_ro
  int lib_interface_gmp_address_family_static_group_create(
        struct nb_cb_create_args *args)
  {
+ #if PIM_IPV == 4
        struct interface *ifp;
        struct ipaddr source_addr;
        struct ipaddr group_addr;
                        return NB_ERR_INCONSISTENCY;
                }
        }
+ #else
+       /* TBD Depends on MLD data structure changes */
+ #endif /* PIM_IPV == 4 */
        return NB_OK;
  }