diff options
| author | David Lamparter <equinox@diac24.net> | 2010-02-03 06:36:04 +0000 |
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2017-08-27 23:40:34 +0200 |
| commit | 5a41e961f8460f4c2126ac3a393e6a73bbe56035 (patch) | |
| tree | af07f194e17be6c5b2c2d4fd9cad8412cf2c8959 /zebra/ioctl.c | |
| parent | a07df329e9a98e297e57e1b18c51fdb11dcc1fb4 (diff) | |
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 835f1f4934..7a3591728e 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; |
