summaryrefslogtreecommitdiffstats
path: root/src/vlibmemory/socket_client.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2018-01-15 01:08:33 -0800
committerDave Barach <openvpp@barachs.net>2018-01-25 23:53:35 +0000
commitb384b543313b6b47a277c903e9d4fcd4343054fa (patch)
tree1996e3a25eb3a32fe5bbc405d75f38dd041a5a40 /src/vlibmemory/socket_client.c
parent4e578068fc3fe8ba176d211123ddd88962dab315 (diff)
session: add support for memfd segments
- update segment manager and session api to work with both flavors of ssvm segments - added generic ssvm slave/master init and del functions - cleanup/refactor tcp_echo - fixed uses of svm fifo pool as vector Change-Id: Ieee8b163faa407da6e77e657a2322de213a9d2a0 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vlibmemory/socket_client.c')
-rw-r--r--src/vlibmemory/socket_client.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c
index 44d21228bfe..a49d335e732 100644
--- a/src/vlibmemory/socket_client.c
+++ b/src/vlibmemory/socket_client.c
@@ -158,6 +158,12 @@ void
vl_socket_client_disconnect (void)
{
socket_client_main_t *scm = &socket_client_main;
+
+ if (vl_mem_client_is_connected ())
+ {
+ vl_client_disconnect_from_vlib_no_unmap ();
+ ssvm_delete_memfd (&scm->memfd_segment);
+ }
if (scm->socket_fd && (close (scm->socket_fd) < 0))
clib_unix_warning ("close");
scm->socket_fd = 0;
@@ -170,19 +176,21 @@ vl_socket_client_enable_disable (int enable)
scm->socket_enable = enable;
}
-static clib_error_t *
-receive_fd_msg (int socket_fd, int *my_fd)
+clib_error_t *
+vl_sock_api_recv_fd_msg (int socket_fd, int *my_fd, u32 wait)
{
+ socket_client_main_t *scm = &socket_client_main;
char msgbuf[16];
char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
struct msghdr mh = { 0 };
struct iovec iov[1];
- ssize_t size;
+ ssize_t size = 0;
struct ucred *cr = 0;
struct cmsghdr *cmsg;
pid_t pid __attribute__ ((unused));
uid_t uid __attribute__ ((unused));
gid_t gid __attribute__ ((unused));
+ f64 timeout;
iov[0].iov_base = msgbuf;
iov[0].iov_len = 5;
@@ -193,8 +201,15 @@ receive_fd_msg (int socket_fd, int *my_fd)
memset (ctl, 0, sizeof (ctl));
- /* receive the incoming message */
- size = recvmsg (socket_fd, &mh, 0);
+ if (wait != ~0)
+ {
+ timeout = clib_time_now (&scm->clib_time) + wait;
+ while (size != 5 && clib_time_now (&scm->clib_time) < timeout)
+ size = recvmsg (socket_fd, &mh, MSG_DONTWAIT);
+ }
+ else
+ size = recvmsg (socket_fd, &mh, 0);
+
if (size != 5)
{
return (size == 0) ? clib_error_return (0, "disconnected") :
@@ -228,11 +243,11 @@ static void vl_api_sock_init_shm_reply_t_handler
(vl_api_sock_init_shm_reply_t * mp)
{
socket_client_main_t *scm = &socket_client_main;
- int my_fd = -1;
- clib_error_t *error;
+ ssvm_private_t *memfd = &scm->memfd_segment;
i32 retval = ntohl (mp->retval);
- ssvm_private_t memfd;
api_main_t *am = &api_main;
+ clib_error_t *error;
+ int my_fd = -1;
u8 *new_name;
if (retval)
@@ -244,25 +259,26 @@ static void vl_api_sock_init_shm_reply_t_handler
/*
* Check the socket for the magic fd
*/
- error = receive_fd_msg (scm->socket_fd, &my_fd);
+ error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5);
if (error)
{
+ clib_error_report (error);
retval = -99;
return;
}
- memset (&memfd, 0, sizeof (memfd));
- memfd.fd = my_fd;
+ memset (memfd, 0, sizeof (*memfd));
+ memfd->fd = my_fd;
/* Note: this closes memfd.fd */
- retval = ssvm_slave_init_memfd (&memfd);
+ retval = ssvm_slave_init_memfd (memfd);
if (retval)
clib_warning ("WARNING: segment map returned %d", retval);
/*
* Pivot to the memory client segment that vpp just created
*/
- am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
+ am->vlib_rp = (void *) (memfd->requested_va + MMAP_PAGESIZE);
am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
new_name = format (0, "%v[shm]%c", scm->name, 0);
@@ -392,6 +408,15 @@ vl_socket_client_init_shm (vl_api_shm_elem_config_t * config)
return 0;
}
+clib_error_t *
+vl_socket_client_recv_fd_msg (int *fd_to_recv, u32 wait)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ if (!scm->socket_fd)
+ return clib_error_return (0, "no socket");
+ return vl_sock_api_recv_fd_msg (scm->client_socket.fd, fd_to_recv, wait);
+}
+
/*
* fd.io coding-style-patch-verification: ON
*
ring.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
#!/usr/bin/env python
""" Container integration tests """

import unittest
from framework import VppTestCase, VppTestRunner, running_extended_tests
from scapy.layers.l2 import Ether
from scapy.packet import Raw
from scapy.layers.inet import IP, UDP, TCP
from scapy.packet import Packet
from socket import inet_pton, AF_INET, AF_INET6
from scapy.layers.inet6 import IPv6, ICMPv6Unknown, ICMPv6EchoRequest
from scapy.layers.inet6 import ICMPv6EchoReply, IPv6ExtHdrRouting
from scapy.layers.inet6 import IPv6ExtHdrFragment
from pprint import pprint
from random import randint
from util import L4_Conn


class Conn(L4_Conn):
    # for now same as L4_Conn
    pass


@unittest.skipUnless(running_extended_tests, "part of extended tests")
class ContainerIntegrationTestCase(VppTestCase):
    """ Container integration extended testcases """

    @classmethod
    def setUpClass(cls):
        super(ContainerIntegrationTestCase, cls).setUpClass()
        # create pg0 and pg1
        cls.create_pg_interfaces(range(2))
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.config_ip6()
            i.resolve_arp()
            i.resolve_ndp()

    @classmethod
    def tearDownClass(cls):
        super(ContainerIntegrationTestCase, cls).tearDownClass()

    def tearDown(self):
        """Run standard test teardown and log various show commands
        """
        super(ContainerIntegrationTestCase, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show ip arp"))
        self.logger.info(self.vapi.cli("show ip6 neighbors"))

    def run_basic_conn_test(self, af, acl_side):
        """ Basic connectivity test """
        conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
        conn1.send_through(0)
        # the return packets should pass
        conn1.send_through(1)

    def run_negative_conn_test(self, af, acl_side):
        """ Packets with local spoofed address """
        conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
        try:
            p2 = conn1.send_through(0).command()
        except:
            # If we asserted while waiting, it's good.
            # the conn should have timed out.
            p2 = None
        self.assert_equal(p2, None, ": packet should have been dropped")

    def test_0010_basic_conn_test(self):
        """ IPv4 basic connectivity test """
        self.run_basic_conn_test(AF_INET, 0)

    def test_0011_basic_conn_test(self):
        """ IPv6 basic connectivity test """
        self.run_basic_conn_test(AF_INET6, 0)

    def test_0050_loopback_prepare_test(self):
        """ Create loopbacks overlapping with remote addresses """
        self.create_loopback_interfaces(2)
        for i in range(2):
            intf = self.lo_interfaces[i]
            intf.admin_up()
            intf.local_ip4 = self.pg_interfaces[i].remote_ip4
            intf.local_ip4_prefix_len = 32
            intf.config_ip4()
            intf.local_ip6 = self.pg_interfaces[i].remote_ip6
            intf.local_ip6_prefix_len = 128
            intf.config_ip6()

    def test_0110_basic_conn_test(self):
        """ IPv4 local-spoof connectivity test """
        self.run_negative_conn_test(AF_INET, 0)

    def test_0111_basic_conn_test(self):
        """ IPv6 local-spoof connectivity test """
        self.run_negative_conn_test(AF_INET, 1)

    def test_0200_basic_conn_test(self):
        """ Configure container commands """
        for i in range(2):
            for addr in [self.pg_interfaces[i].remote_ip4,
                         self.pg_interfaces[i].remote_ip6]:
                self.vapi.ppcli("ip container " + addr + " " +
                                self.pg_interfaces[i].name)
                self.vapi.ppcli("stn rule address " + addr +
                                " interface " + self.pg_interfaces[i].name)

    def test_0210_basic_conn_test(self):
        """ IPv4 test after configuring container """
        self.run_basic_conn_test(AF_INET, 0)

    def test_0211_basic_conn_test(self):
        """ IPv6 test after configuring container """
        self.run_basic_conn_test(AF_INET, 1)

    def test_0300_unconfigure_commands(self):
        """ Unconfigure container commands """
        for i in range(2):
            for addr in [self.pg_interfaces[i].remote_ip4,
                         self.pg_interfaces[i].remote_ip6]:
                self.vapi.ppcli("ip container " + addr + " " +
                                self.pg_interfaces[i].name +
                                " del")
                self.vapi.ppcli("stn rule address " + addr +
                                " interface " + self.pg_interfaces[i].name +
                                " del")

    def test_0410_spoof_test(self):
        """ IPv4 local-spoof after unconfig test """
        self.run_negative_conn_test(AF_INET, 0)

    def test_0411_spoof_test(self):
        """ IPv6 local-spoof after unconfig test """
        self.run_negative_conn_test(AF_INET, 1)