[1/2] socket: Add support for SOCK_PACKET sockets

Submitted by the7winds@yandex.ru on Dec. 20, 2016, 2:17 p.m.

Details

Message ID 20161220141735.7343-1-the7winds@yandex.ru
State Accepted
Series "Series without cover letter"
Commit b49e207f375cc78f0575719a68c1e34adb9baaac
Headers show

Commit Message

the7winds@yandex.ru Dec. 20, 2016, 2:17 p.m.
From: Gleb Valin <the7winds@yandex.ru>

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

Signed-off-by: Gleb Valin <the7winds@yandex.ru>
Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
---
 criu/sk-packet.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/sk-packet.c b/criu/sk-packet.c
index bcd4ff33..a7657bfc 100644
--- a/criu/sk-packet.c
+++ b/criu/sk-packet.c
@@ -1,5 +1,7 @@ 
 #include <linux/if_packet.h>
 #include <sys/socket.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <libnl3/netlink/msg.h>
@@ -403,6 +405,55 @@  static int restore_rings(int sk, PacketSockEntry *psk)
 	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)
 {
 	struct packet_sock_info *psi;
@@ -415,6 +466,9 @@  static int open_packet_sk(struct file_desc *d)
 
 	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);
 	if (sk < 0) {
 		pr_perror("Can't create packet sock");

Comments

Andrey Vagin Dec. 27, 2016, 7:08 p.m.
On Tue, Dec 20, 2016 at 05:17:34PM +0300, the7winds@yandex.ru wrote:
> From: Gleb Valin <the7winds@yandex.ru>
> 
> If socket type is SOCK_PACKET it restores binding with proper address structure.

Hi Gleb,

Could you give more details about this patch? I remember that Pavel did
something with packet sockets.

commit fc7071d05e1b7140bcc39f0a45a86c46bdbcb716
Author: Pavel Emelyanov <xemul@parallels.com>
Date:   Thu Aug 9 16:17:41 2012 +0400

    net: Packet sockets basic support
    
    Support only basic packet socket functionality -- create and bind.
    This should be enough to start testing dhclient inside container.
    Other stuff (filter, mmaps, fanouts, etc.) will come later.
    
    Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

> 
> Signed-off-by: Gleb Valin <the7winds@yandex.ru>
> Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
> ---
>  criu/sk-packet.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/criu/sk-packet.c b/criu/sk-packet.c
> index bcd4ff33..a7657bfc 100644
> --- a/criu/sk-packet.c
> +++ b/criu/sk-packet.c
> @@ -1,5 +1,7 @@
>  #include <linux/if_packet.h>
>  #include <sys/socket.h>
> +#include <net/if.h>
> +#include <sys/ioctl.h>
>  #include <linux/netlink.h>
>  #include <linux/rtnetlink.h>
>  #include <libnl3/netlink/msg.h>
> @@ -403,6 +405,55 @@ static int restore_rings(int sk, PacketSockEntry *psk)
>  	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)
>  {
>  	struct packet_sock_info *psi;
> @@ -415,6 +466,9 @@ static int open_packet_sk(struct file_desc *d)
>  
>  	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);
>  	if (sk < 0) {
>  		pr_perror("Can't create packet sock");
> -- 
> 2.11.0
> 
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
Eugene Batalov Dec. 27, 2016, 7:13 p.m.
Hi Andrei,

this patch is for https://github.com/xemul/criu/issues/73

2016-12-27 22:08 GMT+03:00 Andrei Vagin <avagin@virtuozzo.com>:

> On Tue, Dec 20, 2016 at 05:17:34PM +0300, the7winds@yandex.ru wrote:
> > From: Gleb Valin <the7winds@yandex.ru>
> >
> > If socket type is SOCK_PACKET it restores binding with proper address
> structure.
>
> Hi Gleb,
>
> Could you give more details about this patch? I remember that Pavel did
> something with packet sockets.
>
> commit fc7071d05e1b7140bcc39f0a45a86c46bdbcb716
> Author: Pavel Emelyanov <xemul@parallels.com>
> Date:   Thu Aug 9 16:17:41 2012 +0400
>
>     net: Packet sockets basic support
>
>     Support only basic packet socket functionality -- create and bind.
>     This should be enough to start testing dhclient inside container.
>     Other stuff (filter, mmaps, fanouts, etc.) will come later.
>
>     Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
>
> >
> > Signed-off-by: Gleb Valin <the7winds@yandex.ru>
> > Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
> > ---
> >  criu/sk-packet.c | 54 ++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++
> >  1 file changed, 54 insertions(+)
> >
> > diff --git a/criu/sk-packet.c b/criu/sk-packet.c
> > index bcd4ff33..a7657bfc 100644
> > --- a/criu/sk-packet.c
> > +++ b/criu/sk-packet.c
> > @@ -1,5 +1,7 @@
> >  #include <linux/if_packet.h>
> >  #include <sys/socket.h>
> > +#include <net/if.h>
> > +#include <sys/ioctl.h>
> >  #include <linux/netlink.h>
> >  #include <linux/rtnetlink.h>
> >  #include <libnl3/netlink/msg.h>
> > @@ -403,6 +405,55 @@ static int restore_rings(int sk, PacketSockEntry
> *psk)
> >       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)
> >  {
> >       struct packet_sock_info *psi;
> > @@ -415,6 +466,9 @@ static int open_packet_sk(struct file_desc *d)
> >
> >       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);
> >       if (sk < 0) {
> >               pr_perror("Can't create packet sock");
> > --
> > 2.11.0
> >
> > _______________________________________________
> > CRIU mailing list
> > CRIU@openvz.org
> > https://lists.openvz.org/mailman/listinfo/criu
>
Pavel Emelianov Dec. 29, 2016, 12:35 p.m.
Applied, thanks