const char *ifname,
virSocketAddr *addr,
unsigned int prefix,
- virSocketAddr *broadcast)
+ virSocketAddr *broadcast,
+ virSocketAddr *peer)
{
struct nl_msg *nlmsg = NULL;
struct ifaddrmsg ifa;
unsigned int ifindex;
void *addrData = NULL;
+ void *peerData = NULL;
void *broadcastData = NULL;
size_t addrDataLen;
if (virNetDevGetIPAddressBinary(addr, &addrData, &addrDataLen) < 0)
return NULL;
- if (broadcast && virNetDevGetIPAddressBinary(broadcast, &broadcastData,
- &addrDataLen) < 0)
- return NULL;
+ if (peer && VIR_SOCKET_ADDR_VALID(peer)) {
+ if (virNetDevGetIPAddressBinary(peer, &peerData, &addrDataLen) < 0)
+ return NULL;
+ } else if (broadcast) {
+ if (virNetDevGetIPAddressBinary(broadcast, &broadcastData,
+ &addrDataLen) < 0)
+ return NULL;
+ }
/* Get the interface index */
if ((ifindex = if_nametoindex(ifname)) == 0)
if (nla_put(nlmsg, IFA_LOCAL, addrDataLen, addrData) < 0)
goto buffer_too_small;
- if (nla_put(nlmsg, IFA_ADDRESS, addrDataLen, addrData) < 0)
- goto buffer_too_small;
+ if (peerData) {
+ if (nla_put(nlmsg, IFA_ADDRESS, addrDataLen, peerData) < 0)
+ goto buffer_too_small;
+ }
- if (broadcastData &&
- nla_put(nlmsg, IFA_BROADCAST, addrDataLen, broadcastData) < 0)
- goto buffer_too_small;
+ if (broadcastData) {
+ if (nla_put(nlmsg, IFA_BROADCAST, addrDataLen, broadcastData) < 0)
+ goto buffer_too_small;
+ }
return nlmsg;
* virNetDevSetIPAddress:
* @ifname: the interface name
* @addr: the IP address (IPv4 or IPv6)
+ * @peer: The IP address of peer (IPv4 or IPv6)
* @prefix: number of 1 bits in the netmask
*
* Add an IP address to an interface. This function *does not* remove
*/
int virNetDevSetIPAddress(const char *ifname,
virSocketAddr *addr,
+ virSocketAddr *peer,
unsigned int prefix)
{
virSocketAddr *broadcast = NULL;
struct nlmsghdr *resp = NULL;
unsigned int recvbuflen;
-
/* The caller needs to provide a correct address */
- if (VIR_SOCKET_ADDR_FAMILY(addr) == AF_INET) {
+ if (VIR_SOCKET_ADDR_FAMILY(addr) == AF_INET && !VIR_SOCKET_ADDR_VALID(peer)) {
/* compute a broadcast address if this is IPv4 */
if (VIR_ALLOC(broadcast) < 0)
return -1;
if (!(nlmsg = virNetDevCreateNetlinkAddressMessage(RTM_NEWADDR, ifname,
addr, prefix,
- broadcast)))
+ broadcast, peer)))
goto cleanup;
if (virNetlinkCommand(nlmsg, &resp, &recvbuflen, 0, 0,
if (!(nlmsg = virNetDevCreateNetlinkAddressMessage(RTM_DELADDR, ifname,
addr, prefix,
- NULL)))
+ NULL, NULL)))
goto cleanup;
if (virNetlinkCommand(nlmsg, &resp, &recvbuflen, 0, 0,
int virNetDevSetIPAddress(const char *ifname,
virSocketAddr *addr,
+ virSocketAddr *peer,
unsigned int prefix)
{
virCommandPtr cmd = NULL;
- char *addrstr = NULL, *bcaststr = NULL;
+ char *addrstr = NULL, *bcaststr = NULL, *peerstr = NULL;
virSocketAddr broadcast;
int ret = -1;
if (!(addrstr = virSocketAddrFormat(addr)))
goto cleanup;
+
+ if (VIR_SOCKET_ADDR_VALID(peer) && !(peerstr = virSocketAddrFormat(&peer)))
+ goto cleanup;
+
/* format up a broadcast address if this is IPv4 */
- if ((VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET)) &&
+ if (!peerstr && ((VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET)) &&
((virSocketAddrBroadcastByPrefix(addr, prefix, &broadcast) < 0) ||
- !(bcaststr = virSocketAddrFormat(&broadcast)))) {
+ !(bcaststr = virSocketAddrFormat(&broadcast))))) {
goto cleanup;
}
+
# ifdef IFCONFIG_PATH
cmd = virCommandNew(IFCONFIG_PATH);
virCommandAddArg(cmd, ifname);
else
virCommandAddArg(cmd, "inet");
virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix);
+ if (peerstr)
+ virCommandAddArgList(cmd, "pointopoint", peerstr, NULL);
if (bcaststr)
virCommandAddArgList(cmd, "broadcast", bcaststr, NULL);
virCommandAddArg(cmd, "alias");
cmd = virCommandNew(IP_PATH);
virCommandAddArgList(cmd, "addr", "add", NULL);
virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix);
+ if (peerstr)
+ virCommandAddArgList(cmd, "peer", peerstr, NULL);
if (bcaststr)
virCommandAddArgList(cmd, "broadcast", bcaststr, NULL);
virCommandAddArgList(cmd, "dev", ifname, NULL);
cleanup:
VIR_FREE(addrstr);
VIR_FREE(bcaststr);
+ VIR_FREE(peerstr);
virCommandFree(cmd);
return ret;
}