]> git.puffer.fish Git - matthieu/frr.git/commitdiff
*: clean up ifp-by-local-address function(s)
authorDavid Lamparter <equinox@opensourcerouting.org>
Wed, 23 Jun 2021 14:35:44 +0000 (16:35 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 17 Nov 2021 10:17:44 +0000 (11:17 +0100)
Most users of if_lookup_address_exact only cared about whether the
address is any local address.  Split that off into a separate function.

For the users that actually need the ifp - which I'm about to add a few
of - change it to prefer returning interfaces that are UP.

(Function name changed due to slight change in behavior re. UP state, to
avoid possible bugs from this change.)

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/if.c
lib/if.h
pimd/pim_bsm.c
pimd/pim_igmp.c
pimd/pim_igmp_mtrace.c
pimd/pim_register.c
pimd/pim_rp.c
ripd/rip_snmp.c
staticd/static_routes.c
staticd/static_zebra.c

index a40f04f5a250230c4c49ff46cd1aabbf91906afb..6bfbdf91471d45f1b2e01f7a7f7add000ee91c8e 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -455,36 +455,51 @@ static struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex)
        return NULL;
 }
 
-/* Lookup interface by IP address. */
-struct interface *if_lookup_exact_address(const void *src, int family,
+/* Lookup interface by IP address.
+ *
+ * supersedes if_lookup_exact_address(), which didn't care about up/down
+ * state.  but all users we have either only care if the address is local
+ * (=> use if_address_is_local() please), or care about UP interfaces before
+ * anything else
+ *
+ * to accept only UP interfaces, check if_is_up() on the returned ifp.
+ */
+struct interface *if_lookup_address_local(const void *src, int family,
                                          vrf_id_t vrf_id)
 {
        struct vrf *vrf = vrf_lookup_by_id(vrf_id);
        struct listnode *cnode;
-       struct interface *ifp;
+       struct interface *ifp, *best_down = NULL;
        struct prefix *p;
        struct connected *c;
 
+       if (family != AF_INET && family != AF_INET6)
+               return NULL;
+
        FOR_ALL_INTERFACES (vrf, ifp) {
                for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
                        p = c->address;
 
-                       if (p && (p->family == family)) {
-                               if (family == AF_INET) {
-                                       if (IPV4_ADDR_SAME(
-                                                   &p->u.prefix4,
+                       if (!p || p->family != family)
+                               continue;
+
+                       if (family == AF_INET) {
+                               if (!IPV4_ADDR_SAME(&p->u.prefix4,
                                                    (struct in_addr *)src))
-                                               return ifp;
-                               } else if (family == AF_INET6) {
-                                       if (IPV6_ADDR_SAME(
-                                                   &p->u.prefix6,
+                                       continue;
+                       } else if (family == AF_INET6) {
+                               if (!IPV6_ADDR_SAME(&p->u.prefix6,
                                                    (struct in6_addr *)src))
-                                               return ifp;
-                               }
+                                       continue;
                        }
+
+                       if (if_is_up(ifp))
+                               return ifp;
+                       if (!best_down)
+                               best_down = ifp;
                }
        }
-       return NULL;
+       return best_down;
 }
 
 /* Lookup interface by IP address. */
index 1012bf5557ea22eb56b3dc40a2b988516feeaa12..5f0dc27555058d501cd035909f5d190961ae8bd8 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -511,7 +511,7 @@ extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
 extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
 extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex,
                                                     vrf_id_t vrf_id);
-extern struct interface *if_lookup_exact_address(const void *matchaddr,
+extern struct interface *if_lookup_address_local(const void *matchaddr,
                                                 int family, vrf_id_t vrf_id);
 extern struct connected *if_lookup_address(const void *matchaddr, int family,
                                           vrf_id_t vrf_id);
@@ -520,6 +520,12 @@ extern struct interface *if_lookup_prefix(const struct prefix *prefix,
 size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz,
                           struct interface ***result, vrf_id_t vrf_id);
 
+static inline bool if_address_is_local(const void *matchaddr, int family,
+                                      vrf_id_t vrf_id)
+{
+       return if_lookup_address_local(matchaddr, family, vrf_id) != NULL;
+}
+
 struct vrf;
 extern struct interface *if_lookup_by_name_vrf(const char *name, struct vrf *vrf);
 extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id);
index a3a3426f39098f5beaef0c1fc556e4e9a5420d1e..6c4c7eeb5a54ffff2a51531f13776464a1a43eab 100644 (file)
@@ -1323,8 +1323,8 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
                                return -1;
                        }
                }
-       } else if (if_lookup_exact_address(&ip_hdr->ip_dst, AF_INET,
-                                          pim->vrf->vrf_id)) {
+       } else if (if_address_is_local(&ip_hdr->ip_dst, AF_INET,
+                                      pim->vrf->vrf_id)) {
                /* Unicast BSM received - if ucast bsm not enabled on
                 * the interface, drop it
                 */
index 795c96c83801bad11b058cf5dadab62c5d73c1a4..cd905b3cbdfaf65929091eaadeda78fe146a8380 100644 (file)
@@ -324,7 +324,7 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
                return 0;
        }
 
-       if (if_lookup_exact_address(&from, AF_INET, ifp->vrf_id)) {
+       if (if_address_is_local(&from, AF_INET, ifp->vrf_id)) {
                if (PIM_DEBUG_IGMP_PACKETS)
                        zlog_debug("Recv IGMP query on interface: %s from ourself %s",
                                   ifp->name, from_str);
index 73af44fc4657c365695cdd97b461f3e50995a3bf..42101bc48e7c1933473c747b05ea96ef019ec9d4 100644 (file)
@@ -596,8 +596,8 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
         * if applicable
         */
        if (!IPV4_CLASS_DE(ntohl(ip_hdr->ip_dst.s_addr)))
-               if (!if_lookup_exact_address(&ip_hdr->ip_dst, AF_INET,
-                                            pim->vrf->vrf_id))
+               if (!if_address_is_local(&ip_hdr->ip_dst, AF_INET,
+                                        pim->vrf->vrf_id))
                        return mtrace_forward_packet(pim, ip_hdr);
 
        if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) {
index e2538da36f35face5d0d3101369b420da86b1f12..cc0dace7c2e5d06401e735609a03550cda0cf8bf 100644 (file)
@@ -327,7 +327,7 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
        ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
 
-       if (!pim_rp_check_is_my_ip_address(pim, dest_addr)) {
+       if (!if_address_is_local(&dest_addr, AF_INET, pim->vrf->vrf_id)) {
                if (PIM_DEBUG_PIM_REG) {
                        char dest[INET_ADDRSTRLEN];
 
index f2a969e04a22fc91dbe99da7dd5627c497c7af2d..165138738432e15abe75ed56ee6162afa3d1aebd 100644 (file)
@@ -1178,15 +1178,6 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
        return count;
 }
 
-bool pim_rp_check_is_my_ip_address(struct pim_instance *pim,
-                                  struct in_addr dest_addr)
-{
-       if (if_lookup_exact_address(&dest_addr, AF_INET, pim->vrf->vrf_id))
-               return true;
-
-       return false;
-}
-
 void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
 {
        struct rp_info *rp_info;
index 824cbd8cf152a789a6b2835e6e01c5e79774122c..436dc4de0e4cc9ade7184320335cc24d91b3a457 100644 (file)
@@ -257,7 +257,7 @@ static struct interface *rip2IfLookup(struct variable *v, oid name[],
 
                oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr);
 
-               return if_lookup_exact_address((void *)addr, AF_INET,
+               return if_lookup_address_local((void *)addr, AF_INET,
                                               VRF_DEFAULT);
        } else {
                len = *length - v->namelen;
index 60f384e5172789fbd635e25bad88e4549523f984..45c42ddcefb13548b20e02a311f683d5ba305554 100644 (file)
@@ -199,14 +199,14 @@ bool static_add_nexthop_validate(const char *nh_vrf_name,
        switch (type) {
        case STATIC_IPV4_GATEWAY:
        case STATIC_IPV4_GATEWAY_IFNAME:
-               if (if_lookup_exact_address(&ipaddr->ipaddr_v4, AF_INET,
-                                           vrf->vrf_id))
+               if (if_address_is_local(&ipaddr->ipaddr_v4, AF_INET,
+                                       vrf->vrf_id))
                        return false;
                break;
        case STATIC_IPV6_GATEWAY:
        case STATIC_IPV6_GATEWAY_IFNAME:
-               if (if_lookup_exact_address(&ipaddr->ipaddr_v6, AF_INET6,
-                                           vrf->vrf_id))
+               if (if_address_is_local(&ipaddr->ipaddr_v6, AF_INET6,
+                                       vrf->vrf_id))
                        return false;
                break;
        default:
index 538fae28aa4ece56336bb44817c881a5e4423de6..38b3c93d768f6a63ce153804e57023b97fe3f3df 100644 (file)
@@ -162,14 +162,10 @@ static bool
 static_nexthop_is_local(vrf_id_t vrfid, struct prefix *addr, int family)
 {
        if (family == AF_INET) {
-               if (if_lookup_exact_address(&addr->u.prefix4,
-                                       AF_INET,
-                                       vrfid))
+               if (if_address_is_local(&addr->u.prefix4, AF_INET, vrfid))
                        return true;
        } else if (family == AF_INET6) {
-               if (if_lookup_exact_address(&addr->u.prefix6,
-                                       AF_INET6,
-                                       vrfid))
+               if (if_address_is_local(&addr->u.prefix6, AF_INET6, vrfid))
                        return true;
        }
        return false;