]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: configure PtP address on ifaliasreq systems
authorDavid Lamparter <equinox@diac24.net>
Wed, 3 Feb 2010 06:36:04 +0000 (06:36 +0000)
committerDavid Lamparter <equinox@opensourcerouting.org>
Sun, 27 Aug 2017 21:40:34 +0000 (23:40 +0200)
support configuring a point-to-point address on systems using ioctl
/ struct ifaliasreq. error out when interface/address type mismatch.

tested on FreeBSD 8.0-RELEASE.

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

index 835f1f4934c826edac851036b0889c9f6a1d7251..7a3591728ef2dbceffabd0d3408fb0c1637cbe4e 100644 (file)
@@ -179,10 +179,15 @@ int if_set_prefix(struct interface *ifp, struct connected *ifc)
 {
        int ret;
        struct ifaliasreq addreq;
-       struct sockaddr_in addr;
-       struct sockaddr_in mask;
+       struct sockaddr_in addr, mask, peer;
        struct prefix_ipv4 *p;
 
+       /* don't configure PtP addresses on broadcast ifs or reverse */
+       if (!(ifp->flags & IFF_POINTOPOINT) != !CONNECTED_PEER(ifc)) {
+               errno = EINVAL;
+               return -1;
+       }
+
        p = (struct prefix_ipv4 *)ifc->address;
        rib_lookup_and_pushup(p, ifp->vrf_id);
 
@@ -197,6 +202,18 @@ int if_set_prefix(struct interface *ifp, struct connected *ifc)
 #endif
        memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));
 
+       if (CONNECTED_PEER(ifc)) {
+               p = (struct prefix_ipv4 *)ifc->destination;
+               memset(&mask, 0, sizeof(struct sockaddr_in));
+               peer.sin_addr = p->prefix;
+               peer.sin_family = p->family;
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+               peer.sin_len = sizeof(struct sockaddr_in);
+#endif
+               memcpy(&addreq.ifra_broadaddr, &peer,
+                      sizeof(struct sockaddr_in));
+       }
+
        memset(&mask, 0, sizeof(struct sockaddr_in));
        masklen2ip(p->prefixlen, &mask.sin_addr);
        mask.sin_family = p->family;
@@ -217,10 +234,15 @@ int if_unset_prefix(struct interface *ifp, struct connected *ifc)
 {
        int ret;
        struct ifaliasreq addreq;
-       struct sockaddr_in addr;
-       struct sockaddr_in mask;
+       struct sockaddr_in addr, mask, peer;
        struct prefix_ipv4 *p;
 
+       /* this would probably wreak havoc */
+       if (!(ifp->flags & IFF_POINTOPOINT) != !CONNECTED_PEER(ifc)) {
+               errno = EINVAL;
+               return -1;
+       }
+
        p = (struct prefix_ipv4 *)ifc->address;
 
        memset(&addreq, 0, sizeof addreq);
@@ -234,6 +256,18 @@ int if_unset_prefix(struct interface *ifp, struct connected *ifc)
 #endif
        memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));
 
+       if (CONNECTED_PEER(ifc)) {
+               p = (struct prefix_ipv4 *)ifc->destination;
+               memset(&mask, 0, sizeof(struct sockaddr_in));
+               peer.sin_addr = p->prefix;
+               peer.sin_family = p->family;
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+               peer.sin_len = sizeof(struct sockaddr_in);
+#endif
+               memcpy(&addreq.ifra_broadaddr, &peer,
+                      sizeof(struct sockaddr_in));
+       }
+
        memset(&mask, 0, sizeof(struct sockaddr_in));
        masklen2ip(p->prefixlen, &mask.sin_addr);
        mask.sin_family = p->family;