2009-06-15 15:11:30 -07:00
|
|
|
/*
|
2010-01-08 16:45:14 -08:00
|
|
|
* Copyright (c) 2009, 2010 Nicira Networks.
|
2009-06-15 15:11:30 -07:00
|
|
|
* Distributed under the terms of the GNU GPL version 2.
|
|
|
|
|
*
|
|
|
|
|
* Significant portions of this file may be copied from parts of the Linux
|
|
|
|
|
* kernel, by Linus Torvalds and others.
|
|
|
|
|
*/
|
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
/* Interface exported by openvswitch_mod. */
|
|
|
|
|
|
|
|
|
|
#ifndef DATAPATH_H
|
|
|
|
|
#define DATAPATH_H 1
|
|
|
|
|
|
|
|
|
|
#include <asm/page.h>
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
|
#include <linux/workqueue.h>
|
2010-07-28 18:20:43 -07:00
|
|
|
#include <linux/seqlock.h>
|
2009-07-08 13:19:16 -07:00
|
|
|
#include <linux/skbuff.h>
|
2009-06-12 16:45:01 -07:00
|
|
|
#include <linux/version.h>
|
2010-11-22 14:17:24 -08:00
|
|
|
|
|
|
|
|
#include "checksum.h"
|
2009-07-08 13:19:16 -07:00
|
|
|
#include "flow.h"
|
2009-08-05 12:56:23 -07:00
|
|
|
#include "dp_sysfs.h"
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2010-04-12 15:53:39 -04:00
|
|
|
struct vport;
|
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
/* Mask for the priority bits in a vlan header. If we ever merge upstream
|
|
|
|
|
* then this should go into include/linux/if_vlan.h. */
|
|
|
|
|
#define VLAN_PCP_MASK 0xe000
|
2009-10-08 10:37:43 -07:00
|
|
|
#define VLAN_PCP_SHIFT 13
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2009-09-11 14:32:50 -07:00
|
|
|
#define DP_MAX_PORTS 1024
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2010-01-04 13:08:37 -08:00
|
|
|
#define DP_N_QUEUES 3
|
2009-07-08 13:19:16 -07:00
|
|
|
#define DP_MAX_QUEUE_LEN 100
|
|
|
|
|
|
2010-01-08 16:45:14 -08:00
|
|
|
/**
|
|
|
|
|
* struct dp_stats_percpu - per-cpu packet processing statistics for a given
|
|
|
|
|
* datapath.
|
|
|
|
|
* @n_frags: Number of IP fragments processed by datapath.
|
|
|
|
|
* @n_hit: Number of received packets for which a matching flow was found in
|
|
|
|
|
* the flow table.
|
|
|
|
|
* @n_miss: Number of received packets that had no matching flow in the flow
|
|
|
|
|
* table. The sum of @n_hit and @n_miss is the number of packets that have
|
|
|
|
|
* been received by the datapath.
|
|
|
|
|
* @n_lost: Number of received packets that had no matching flow in the flow
|
|
|
|
|
* table that could not be sent to userspace (normally due to an overflow in
|
|
|
|
|
* one of the datapath's queues).
|
|
|
|
|
*/
|
2009-07-08 13:19:16 -07:00
|
|
|
struct dp_stats_percpu {
|
|
|
|
|
u64 n_frags;
|
|
|
|
|
u64 n_hit;
|
|
|
|
|
u64 n_missed;
|
|
|
|
|
u64 n_lost;
|
2010-07-28 18:20:43 -07:00
|
|
|
seqcount_t seqlock;
|
2009-07-08 13:19:16 -07:00
|
|
|
};
|
|
|
|
|
|
2010-01-04 13:08:37 -08:00
|
|
|
/**
|
|
|
|
|
* struct datapath - datapath for flow-based packet switching
|
|
|
|
|
* @mutex: Mutual exclusion for ioctls.
|
|
|
|
|
* @dp_idx: Datapath number (index into the dps[] array in datapath.c).
|
sflow: Fix sFlow sampling structure.
According to Neil McKee, in an email archived at
http://openvswitch.org/pipermail/dev_openvswitch.org/2010-January/000934.html:
The containment rule is that a given sflow-datasource (sampler or
poller) should be scoped within only one sflow-agent (or
sub-agent). So the issue arrises when you have two
switches/datapaths defined on the same host being managed with
the same IP address: each switch is a separate sub-agent, so they
can run independently (e.g. with their own sequence numbers) but
they can't both claim to speak for the same sflow-datasource.
Specifically, they can't both represent the <ifindex>:0
data-source. This containment rule is necessary so that the
sFlow collector can scale and combine the results accurately.
One option would be to stick with the <ifindex>:0 data-source but
elevate it to be global across all bridges, with a global
sample_pool and a global sflow_agent. Not tempting. Better to
go the other way and allow each interface to have it's own
sampler, just as it already has it's own poller. The ifIndex
numbers are globally unique across all switches/datapaths on the
host, so the containment is now clean. Datasource <ifindex>:5
might be on one switch, whille <ifindex>:7 can be on another.
Other benefits are that 1) you can support the option of
overriding the default sampling-rate on an interface-by-interface
basis, and 2) this is how most sFlow implementations are coded,
so there will be no surprises or interoperability issues with any
sFlow collectors out there.
This commit implements the approach suggested by Neil.
This commit uses an atomic_t to represent the sampling pool. This is
because we do want access to it to be atomic, but we expect that it will
"mostly" be accessed from a single CPU at a time. Perhaps this is a bad
assumption; we can always switch to another form of synchronization later.
CC: Neil McKee <neil.mckee@inmon.com>
2010-01-20 13:52:42 -08:00
|
|
|
* @ifobj: Represents /sys/class/net/<devname>/brif.
|
2010-01-04 13:08:37 -08:00
|
|
|
* @drop_frags: Drop all IP fragments if nonzero.
|
|
|
|
|
* @queues: %DP_N_QUEUES sets of queued packets for userspace to handle.
|
|
|
|
|
* @waitqueue: Waitqueue, for waiting for new packets in @queues.
|
|
|
|
|
* @n_flows: Number of flows currently in flow table.
|
|
|
|
|
* @table: Current flow table (RCU protected).
|
|
|
|
|
* @n_ports: Number of ports currently in @ports.
|
2010-12-03 13:09:26 -08:00
|
|
|
* @ports: Map from port number to &struct vport. %ODPP_LOCAL port
|
2010-01-04 13:08:37 -08:00
|
|
|
* always exists, other ports may be %NULL.
|
|
|
|
|
* @port_list: List of all ports in @ports in arbitrary order.
|
|
|
|
|
* @stats_percpu: Per-CPU datapath statistics.
|
2010-01-08 16:44:43 -08:00
|
|
|
* @sflow_probability: Number of packets out of UINT_MAX to sample to the
|
|
|
|
|
* %ODPL_SFLOW queue, e.g. (@sflow_probability/UINT_MAX) is the probability of
|
|
|
|
|
* sampling a given packet.
|
2010-01-04 13:08:37 -08:00
|
|
|
*/
|
2009-07-08 13:19:16 -07:00
|
|
|
struct datapath {
|
|
|
|
|
struct mutex mutex;
|
|
|
|
|
int dp_idx;
|
|
|
|
|
struct kobject ifobj;
|
|
|
|
|
|
|
|
|
|
int drop_frags;
|
|
|
|
|
|
|
|
|
|
/* Queued data. */
|
|
|
|
|
struct sk_buff_head queues[DP_N_QUEUES];
|
|
|
|
|
wait_queue_head_t waitqueue;
|
|
|
|
|
|
|
|
|
|
/* Flow table. */
|
2010-04-02 16:46:18 -04:00
|
|
|
struct tbl *table;
|
2009-07-08 13:19:16 -07:00
|
|
|
|
|
|
|
|
/* Switch ports. */
|
|
|
|
|
unsigned int n_ports;
|
2010-12-03 13:09:26 -08:00
|
|
|
struct vport *ports[DP_MAX_PORTS];
|
2010-01-04 13:08:37 -08:00
|
|
|
struct list_head port_list;
|
2009-07-08 13:19:16 -07:00
|
|
|
|
|
|
|
|
/* Stats. */
|
|
|
|
|
struct dp_stats_percpu *stats_percpu;
|
2010-01-04 13:08:37 -08:00
|
|
|
|
|
|
|
|
/* sFlow Sampling */
|
|
|
|
|
unsigned int sflow_probability;
|
2009-07-08 13:19:16 -07:00
|
|
|
};
|
|
|
|
|
|
2010-02-28 12:17:16 -05:00
|
|
|
/**
|
|
|
|
|
* struct ovs_skb_cb - OVS data in skb CB
|
2010-12-03 13:09:26 -08:00
|
|
|
* @vport: The datapath port on which the skb entered the switch.
|
2010-08-29 10:49:11 -07:00
|
|
|
* @flow: The flow associated with this packet. May be %NULL if no flow.
|
2010-02-28 12:17:16 -05:00
|
|
|
* @ip_summed: Consistently stores L4 checksumming status across different
|
|
|
|
|
* kernel versions.
|
2010-12-10 10:42:42 -08:00
|
|
|
* @tun_id: ID of the tunnel that encapsulated this packet. It is 0 if the
|
|
|
|
|
* packet was not received on a tunnel.
|
2010-02-28 12:17:16 -05:00
|
|
|
*/
|
|
|
|
|
struct ovs_skb_cb {
|
2010-12-03 13:09:26 -08:00
|
|
|
struct vport *vport;
|
2010-08-29 10:49:11 -07:00
|
|
|
struct sw_flow *flow;
|
2010-11-22 14:17:24 -08:00
|
|
|
#ifdef NEED_CSUM_NORMALIZE
|
2010-04-12 11:49:16 -04:00
|
|
|
enum csum_type ip_summed;
|
2010-11-22 14:17:24 -08:00
|
|
|
#endif
|
2010-12-10 10:42:42 -08:00
|
|
|
__be64 tun_id;
|
2010-02-28 12:17:16 -05:00
|
|
|
};
|
|
|
|
|
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
|
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
extern struct notifier_block dp_device_notifier;
|
|
|
|
|
extern int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd);
|
|
|
|
|
|
2010-12-03 13:09:26 -08:00
|
|
|
void dp_process_received_packet(struct vport *, struct sk_buff *);
|
|
|
|
|
int dp_detach_port(struct vport *);
|
2010-12-10 10:42:42 -08:00
|
|
|
int dp_output_control(struct datapath *, struct sk_buff *, int, u64 arg);
|
2009-08-01 00:09:56 -07:00
|
|
|
int dp_min_mtu(const struct datapath *dp);
|
2010-04-12 15:53:39 -04:00
|
|
|
void set_internal_devs_mtu(const struct datapath *dp);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
|
|
|
|
struct datapath *get_dp(int dp_idx);
|
2010-04-12 15:53:39 -04:00
|
|
|
const char *dp_name(const struct datapath *dp);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
|
|
|
|
#endif /* datapath.h */
|