]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: add connected_check_ptp infrastructure
authorDavid Lamparter <equinox@diac24.net>
Sat, 30 Jan 2010 11:10:23 +0000 (12:10 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Sun, 27 Aug 2017 21:31:02 +0000 (23:31 +0200)
add a connected_check_ptp function which does the same as
connected_check, but takes an additional peer prefix argument.

also fix related prefixlen mixup in PtP addresses (the local part of a
PtP address always is /32, but previously the peer mask got copied.)

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
zebra/connected.c
zebra/connected.h
zebra/interface.c

index 701314f2461acd56423217b842712ecd3d7577b1..1368a1228951298703a7c6c8cc928657846e6998 100644 (file)
@@ -100,8 +100,10 @@ static void connected_announce(struct interface *ifp, struct connected *ifc)
 }
 
 /* If same interface address is already exist... */
-struct connected *connected_check(struct interface *ifp, struct prefix *p)
+struct connected *connected_check(struct interface *ifp,
+                                 union prefixconstptr pu)
 {
+       const struct prefix *p = pu.p;
        struct connected *ifc;
        struct listnode *node;
 
@@ -112,6 +114,33 @@ struct connected *connected_check(struct interface *ifp, struct prefix *p)
        return NULL;
 }
 
+/* same, but with peer address */
+struct connected *connected_check_ptp(struct interface *ifp,
+                                     union prefixconstptr pu,
+                                     union prefixconstptr du)
+{
+       const struct prefix *p = pu.p;
+       const struct prefix *d = du.p;
+       struct connected *ifc;
+       struct listnode *node;
+
+       /* ignore broadcast addresses */
+       if (p->prefixlen != IPV4_MAX_PREFIXLEN)
+               d = NULL;
+
+       for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+               if (!prefix_same(ifc->address, p))
+                       continue;
+               if (!CONNECTED_PEER(ifc) && !d)
+                       return ifc;
+               if (CONNECTED_PEER(ifc) && d
+                   && prefix_same(ifc->destination, d))
+                       return ifc;
+       }
+
+       return NULL;
+}
+
 /* Check if two ifc's describe the same address in the same state */
 static int connected_same(struct connected *ifc1, struct connected *ifc2)
 {
@@ -145,7 +174,8 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
        struct connected *current;
 
        /* Check same connected route. */
-       if ((current = connected_check(ifp, (struct prefix *)ifc->address))) {
+       current = connected_check_ptp(ifp, ifc->address, ifc->destination);
+       if (current) {
                if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
                        SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
 
@@ -238,7 +268,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
        p = prefix_ipv4_new();
        p->family = AF_INET;
        p->prefix = *addr;
-       p->prefixlen = prefixlen;
+       p->prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
+                                                        : prefixlen;
        ifc->address = (struct prefix *)p;
 
        /* If there is broadcast or peer address. */
@@ -350,15 +381,25 @@ void connected_delete_ipv4(struct interface *ifp, int flags,
                           struct in_addr *addr, u_char prefixlen,
                           struct in_addr *broad)
 {
-       struct prefix_ipv4 p;
+       struct prefix_ipv4 p, d;
        struct connected *ifc;
 
        memset(&p, 0, sizeof(struct prefix_ipv4));
        p.family = AF_INET;
        p.prefix = *addr;
-       p.prefixlen = prefixlen;
+       p.prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
+                                                       : prefixlen;
+
+       if (broad) {
+               memset(&d, 0, sizeof(struct prefix_ipv4));
+               d.family = AF_INET;
+               d.prefix = *broad;
+               d.prefixlen = prefixlen;
+               ifc = connected_check_ptp(ifp, (struct prefix *)&p,
+                                         (struct prefix *)&d);
+       } else
+               ifc = connected_check_ptp(ifp, (struct prefix *)&p, NULL);
 
-       ifc = connected_check(ifp, (struct prefix *)&p);
        if (!ifc)
                return;
 
index eaf79fe9aadd5b3a00501c9764a954ebb8d2188b..b67442fa3b718f0195809e28dcf97ddb21fd7b48 100644 (file)
 #define _ZEBRA_CONNECTED_H
 
 extern struct connected *connected_check(struct interface *ifp,
-                                        struct prefix *p);
+                                        union prefixconstptr p);
+extern struct connected *connected_check_ptp(struct interface *ifp,
+                                            union prefixconstptr p,
+                                            union prefixconstptr d);
 
 extern void connected_add_ipv4(struct interface *ifp, int flags,
                               struct in_addr *addr, u_char prefixlen,
index c17e408ea0e062903fb19ec91a3969228f57854d..9b4af1786e6b91aee95e4f05c28d76337ec5c768 100644 (file)
@@ -242,7 +242,7 @@ int if_subnet_add(struct interface *ifp, struct connected *ifc)
        /* Get address derived subnet node and associated address list, while
           marking
           address secondary attribute appropriately. */
-       cp = *ifc->address;
+       cp = *CONNECTED_PREFIX(ifc);
        apply_mask(&cp);
        rn = route_node_get(zebra_if->ipv4_subnets, &cp);
 
@@ -267,12 +267,16 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc)
        struct route_node *rn;
        struct zebra_if *zebra_if;
        struct list *addr_list;
+       struct prefix cp;
 
        assert(ifp && ifp->info && ifc);
        zebra_if = ifp->info;
 
+       cp = *CONNECTED_PREFIX(ifc);
+       apply_mask(&cp);
+
        /* Get address derived subnet node. */
-       rn = route_node_lookup(zebra_if->ipv4_subnets, ifc->address);
+       rn = route_node_lookup(zebra_if->ipv4_subnets, &cp);
        if (!(rn && rn->info)) {
                zlog_warn(
                        "Trying to remove an address from an unknown subnet."
@@ -966,6 +970,8 @@ static void connected_dump_vty(struct vty *vty, struct connected *connected)
                vty_out(vty,
                        (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
                prefix_vty_out(vty, connected->destination);
+               if (CONNECTED_PEER(connected))
+                       vty_out(vty, "/%d", connected->destination->prefixlen);
        }
 
        if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))