Commit 6d86d8d0 authored by Gleb Valin's avatar Gleb Valin Committed by Pavel Emelyanov

socket: Add support for SOCK_PACKET sockets

If socket type is SOCK_PACKET it restores binding with proper address structure.

https://github.com/xemul/criu/issues/73
travis-ci: success for series starting with [1/2] socket: Add support for SOCK_PACKET sockets
Signed-off-by: 's avatarGleb Valin <the7winds@yandex.ru>
Signed-off-by: 's avatarEugene Batalov <eabatalov89@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent b82fc5e0
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <libnl3/netlink/msg.h> #include <libnl3/netlink/msg.h>
...@@ -403,6 +405,55 @@ static int restore_rings(int sk, PacketSockEntry *psk) ...@@ -403,6 +405,55 @@ static int restore_rings(int sk, PacketSockEntry *psk)
return 0; return 0;
} }
static int open_packet_sk_spkt(PacketSockEntry *pse)
{
struct sockaddr addr_spkt;
int sk;
sk = socket(PF_PACKET, pse->type, pse->protocol);
if (sk < 0) {
pr_perror("Can't create packet socket");
return -1;
}
memset(&addr_spkt, 0, sizeof(addr_spkt));
addr_spkt.sa_family = AF_PACKET;
// if the socket was bound to any device
if (pse->ifindex > 0) {
const size_t sa_data_size = sizeof(addr_spkt.sa_data);
struct ifreq req;
memset(&req, 0, sizeof(req));
req.ifr_ifindex = pse->ifindex;
if (ioctl(sk, SIOCGIFNAME, &req) < 0) {
pr_perror("Can't get interface name (ifindex %d)", pse->ifindex);
goto err;
}
strncpy(addr_spkt.sa_data, req.ifr_name, sa_data_size);
addr_spkt.sa_data[sa_data_size - 1] = 0;
if (bind(sk, &addr_spkt, sizeof(addr_spkt)) < 0) {
pr_perror("Can't bind packet socket to %s", req.ifr_name);
goto err;
}
}
if (rst_file_params(sk, pse->fown, pse->flags))
goto err;
if (restore_socket_opts(sk, pse->opts))
goto err;
return sk;
err:
close(sk);
return -1;
}
static int open_packet_sk(struct file_desc *d) static int open_packet_sk(struct file_desc *d)
{ {
struct packet_sock_info *psi; struct packet_sock_info *psi;
...@@ -415,6 +466,9 @@ static int open_packet_sk(struct file_desc *d) ...@@ -415,6 +466,9 @@ static int open_packet_sk(struct file_desc *d)
pr_info("Opening packet socket id %#x\n", pse->id); pr_info("Opening packet socket id %#x\n", pse->id);
if (pse->type == SOCK_PACKET)
return open_packet_sk_spkt(pse);
sk = socket(PF_PACKET, pse->type, pse->protocol); sk = socket(PF_PACKET, pse->type, pse->protocol);
if (sk < 0) { if (sk < 0) {
pr_perror("Can't create packet sock"); pr_perror("Can't create packet sock");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment