{
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);
#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;
{
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);
#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;