diff options
author | David Lamparter <equinox@diac24.net> | 2010-02-03 07:36:04 +0100 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2017-08-27 23:40:34 +0200 |
commit | 5a41e961f8460f4c2126ac3a393e6a73bbe56035 (patch) | |
tree | af07f194e17be6c5b2c2d4fd9cad8412cf2c8959 /zebra/ioctl.c | |
parent | zebra: add '[no] ip address A.B.C.D peer A.B.C.D/M' (diff) | |
download | frr-5a41e961f8460f4c2126ac3a393e6a73bbe56035.tar.xz frr-5a41e961f8460f4c2126ac3a393e6a73bbe56035.zip |
zebra: configure PtP address on ifaliasreq systems
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>
Diffstat (limited to 'zebra/ioctl.c')
-rw-r--r-- | zebra/ioctl.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 835f1f493..7a3591728 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -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; |