From 5a41e961f8460f4c2126ac3a393e6a73bbe56035 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 3 Feb 2010 06:36:04 +0000 Subject: [PATCH] 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 --- zebra/ioctl.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file 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; -- 2.39.5