chain.c \
crc32.c \
datapath.c \
- datapath_t.c \
dp_dev.c \
flow.c \
forward.c \
compat.h \
crc32.h \
datapath.h \
- datapath_t.h \
dp_dev.h \
flow.h \
forward.h \
#include "dp_dev.h"
#include "forward.h"
#include "flow.h"
-#include "datapath_t.h"
#include "compat.h"
.dumpit = dp_genl_openflow_dumpit,
};
-static struct nla_policy dp_genl_benchmark_policy[DP_GENL_A_MAX + 1] = {
- [DP_GENL_A_DP_IDX] = { .type = NLA_U32 },
- [DP_GENL_A_NPACKETS] = { .type = NLA_U32 },
- [DP_GENL_A_PSIZE] = { .type = NLA_U32 },
-};
-
-static struct genl_ops dp_genl_ops_benchmark_nl = {
- .cmd = DP_GENL_C_BENCHMARK_NL,
- .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
- .policy = dp_genl_benchmark_policy,
- .doit = dp_genl_benchmark_nl,
- .dumpit = NULL,
-};
-
static struct genl_ops *dp_genl_all_ops[] = {
/* Keep this operation first. Generic Netlink dispatching
* looks up operations with linear search, so we want it at the
&dp_genl_ops_query_dp,
&dp_genl_ops_add_port,
&dp_genl_ops_del_port,
- &dp_genl_ops_benchmark_nl,
};
static int dp_init_netlink(void)
+++ /dev/null
-#include "datapath_t.h"
-#include <linux/skbuff.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/if_ether.h>
-#include <linux/udp.h>
-#include <linux/rcupdate.h>
-
-#include "datapath.h"
-
-static struct sk_buff *
-gen_sk_buff(struct datapath *dp, uint32_t packet_size)
-{
- int in_port;
- struct sk_buff *skb;
- struct ethhdr *eh;
- struct iphdr *ih;
- struct udphdr *uh;
-
- for (in_port = 0; in_port < OFPP_MAX; in_port++) {
- if (dp->ports[in_port] != NULL)
- break;
- }
-
- if (in_port == OFPP_MAX) {
- printk("benchmark: no in_port to send packets as\n");
- return NULL;
- }
-
- skb = alloc_skb(packet_size, GFP_ATOMIC);
- if (!skb) {
- printk("benchmark: cannot allocate skb for benchmark\n");
- return NULL;
- }
-
- skb_put(skb, packet_size);
- skb_set_mac_header(skb, 0);
- eh = eth_hdr(skb);
- memcpy(eh->h_dest, "\x12\x34\x56\x78\x9a\xbc", ETH_ALEN);
- memcpy(eh->h_source, "\xab\xcd\xef\x12\x34\x56", ETH_ALEN);
- eh->h_proto = htons(ETH_P_IP);
- skb_set_network_header(skb, sizeof(*eh));
- ih = ip_hdr(skb);
- ih->ihl = 5;
- ih->version = IPVERSION;
- ih->tos = 0;
- ih->tot_len = htons(packet_size - sizeof(*eh));
- ih->id = htons(12345);
- ih->frag_off = 0;
- ih->ttl = IPDEFTTL;
- ih->protocol = IPPROTO_UDP;
- ih->check = 0; /* want this to be right?! */
- ih->saddr = 0x12345678;
- ih->daddr = 0x1234abcd;
- skb_set_transport_header(skb, sizeof(*eh) + sizeof(*ih));
- uh = udp_hdr(skb);
- uh->source = htons(1234);
- uh->dest = htons(5678);
- uh->len = htons(packet_size - sizeof(*eh) - sizeof(*ih));
- uh->check = 0;
- if (dp_set_origin(dp, in_port, skb)) {
- printk("benchmark: could not set origin\n");
- kfree_skb(skb);
- return NULL;
- }
-
- return skb;
-}
-
-int
-dp_genl_benchmark_nl(struct sk_buff *skb, struct genl_info *info)
-{
- struct datapath *dp;
- uint32_t num_packets = 0;
- int i, err = 0;
- struct sk_buff *skb2;
-
- if (!info->attrs[DP_GENL_A_DP_IDX] || !info->attrs[DP_GENL_A_NPACKETS]
- || !info->attrs[DP_GENL_A_PSIZE])
- return -EINVAL;
-
- num_packets = nla_get_u32((info->attrs[DP_GENL_A_NPACKETS]));
-
- rcu_read_lock();
- dp = dp_get(nla_get_u32((info->attrs[DP_GENL_A_DP_IDX])));
- if (!dp)
- err = -ENOENT;
- else {
- if (num_packets == 0)
- goto benchmark_unlock;
-
- skb2 = gen_sk_buff(dp, nla_get_u32((info->attrs[DP_GENL_A_PSIZE])));
- if (skb2 == NULL) {
- err = -ENOMEM;
- goto benchmark_unlock;
- }
-
- for (i = 0; i < num_packets; i++) {
- struct sk_buff *copy = skb_get(skb2);
- if (copy == NULL) {
- printk("benchmark: skb_get failed\n");
- err = -ENOMEM;
- break;
- }
- if ((err = dp_output_control(dp, copy, -1,
- 0, OFPR_ACTION)))
- {
- printk("benchmark: output control ret %d on iter %d\n", err, i);
- break;
- }
- }
- kfree_skb(skb2);
- }
-
-benchmark_unlock:
- rcu_read_unlock();
- return err;
-}
+++ /dev/null
-#ifndef DATAPATH_T_H
-#define DATAPATH_T_H 1
-
-#include <linux/socket.h>
-#include <linux/capability.h>
-#include <linux/skbuff.h>
-#include <net/genetlink.h>
-#include "openflow-netlink.h"
-
-int dp_genl_benchmark_nl(struct sk_buff *, struct genl_info *);
-
-#endif
/flow.c
/forward.c
/forward_t.c
-/datapath_t.c
/table-hash.c
/table-linear.c
/table-mac.c
/crc32.c
/crc_t.c
/datapath.c
-/datapath_t.c
/dp_dev.c
/flow.c
/forward.c
int dpif_del_dp(struct dpif *);
int dpif_add_port(struct dpif *, const char *netdev);
int dpif_del_port(struct dpif *, const char *netdev);
-int dpif_benchmark_nl(struct dpif *, uint32_t, uint32_t);
#endif /* dpif.h */
DP_GENL_C_DEL_PORT, /* Remove port from datapath. */
DP_GENL_C_OPENFLOW, /* Encapsulated OpenFlow protocol. */
- DP_GENL_C_BENCHMARK_NL, /* Benchmark netlink connection */
-
__DP_GENL_C_MAX,
DP_GENL_C_MAX = __DP_GENL_C_MAX - 1
};
{
return send_mgmt_command(dp, DP_GENL_C_DEL_PORT, netdev);
}
-
-/* Tells dp to send num_packets up through netlink for benchmarking*/
-int
-dpif_benchmark_nl(struct dpif *dp, uint32_t num_packets, uint32_t packet_size)
-{
- struct buffer request;
- int retval;
-
- buffer_init(&request, 0);
- nl_msg_put_genlmsghdr(&request, dp->sock, 0, openflow_family,
- NLM_F_REQUEST, DP_GENL_C_BENCHMARK_NL, 1);
- nl_msg_put_u32(&request, DP_GENL_A_DP_IDX, dp->dp_idx);
- nl_msg_put_u32(&request, DP_GENL_A_NPACKETS, num_packets);
- nl_msg_put_u32(&request, DP_GENL_A_PSIZE, packet_size);
- retval = nl_sock_send(dp->sock, &request, true);
- buffer_uninit(&request);
-
- return retval;
-}
\f
static const struct nl_policy openflow_multicast_policy[] = {
[DP_GENL_A_DP_IDX] = { .type = NL_A_U32 },
\fIdp_idx\fR to its controller, where \fIdp_idx\fR is the ID of an
existing datapath.
-.TP
-\fBbenchmark-nl nl:\fIdp_idx n size\fR
-Checks the netlink performance between the kernel and userspace.
-This is done by sending \fIN\fR packets of \fIsize\fR bytes from
-the kernel module to dpctl.
-
.PP
The following commands can be used regardless of the connection method.
" addif nl:DP_ID IFACE add IFACE as a port on DP_ID\n"
" delif nl:DP_ID IFACE delete IFACE as a port on DP_ID\n"
" monitor nl:DP_ID print packets received\n"
- " benchmark-nl nl:DP_ID N SIZE send N packets of SIZE bytes\n"
#endif
"\nCommands that apply to local datapaths and remote switches:\n"
" show SWITCH show information\n"
buffer_delete(b);
}
}
-
-#define BENCHMARK_INCR 100
-
-static void do_benchmark_nl(int argc UNUSED, char *argv[])
-{
- struct dpif dp;
- uint32_t num_packets, i, milestone;
- struct timeval start, end;
-
- open_nl_vconn(argv[1], false, &dp);
- num_packets = atoi(argv[2]);
- milestone = BENCHMARK_INCR;
- run(dpif_benchmark_nl(&dp, num_packets, atoi(argv[3])), "benchmark_nl");
- if (gettimeofday(&start, NULL) == -1) {
- run(errno, "gettimeofday");
- }
- for (i = 0; i < num_packets;i++) {
- struct buffer *b;
- run(dpif_recv_openflow(&dp, &b, true), "dpif_recv_openflow");
- if (i == milestone) {
- gettimeofday(&end, NULL);
- printf("%u packets received in %f ms\n",
- BENCHMARK_INCR,
- (1000*(double)(end.tv_sec - start.tv_sec))
- + (.001*(end.tv_usec - start.tv_usec)));
- milestone += BENCHMARK_INCR;
- start = end;
- }
- buffer_delete(b);
- }
- gettimeofday(&end, NULL);
- printf("%u packets received in %f ms\n",
- i - (milestone - BENCHMARK_INCR),
- (1000*(double)(end.tv_sec - start.tv_sec))
- + (.001*(end.tv_usec - start.tv_usec)));
-
- dpif_close(&dp);
-}
#endif /* HAVE_NETLINK */
\f
/* Generic commands. */
{ "deldp", 1, 1, do_del_dp },
{ "addif", 2, 2, do_add_port },
{ "delif", 2, 2, do_del_port },
- { "benchmark-nl", 3, 3, do_benchmark_nl },
#endif
{ "show", 1, 1, do_show },