+v0.2.2 - 13 Apr 2008
+--------------------
+ - Removed MAC tables
+ - Various bug fixes and tweaks
+
v0.2.1 - 28 Mar 2008
--------------------
- Fixed build problem when SSL enabled
OpenFlow switches, commanding them to act as regular MAC
learning switches.
- - vlogconf, a utility that can adjust the logging levels of a
+ - vlogconf, a utility that can adjust the logging levels of a
running secchan or controller.
- ofp-pki, a utility for creating and managing the public-key
AC_PROG_CC
AC_PROG_CPP
+AC_PROG_LD
AC_USE_SYSTEM_EXTENSIONS
AC_CHECK_HEADER([linux/netlink.h],
[HAVE_NETLINK=yes],
[HAVE_NETLINK=no],
- [#include <sys/socket.h>])
+ [#include <sys/socket.h>
+#include <linux/types.h>])
AM_CONDITIONAL([HAVE_NETLINK], [test "$HAVE_NETLINK" = yes])
if test "$HAVE_NETLINK" = yes; then
AC_DEFINE([HAVE_NETLINK], [1],
EXTRA_DIST = linux-2.6 linux-2.4\
datapath.c snap.h chain.c crc32.c crc_t.c\
- flow.h forward.h table-hash.c table-mac.c\
+ flow.h forward.h table-hash.c\
unit.c unit.h datapath.h chain.h crc32.h\
flow.c forward.c forward_t.c table.h\
table-linear.c table_t.c unit-exports.c\
return NULL;
chain->dp = dp;
- if (add_table(chain, table_mac_create(TABLE_MAC_NUM_BUCKETS,
- TABLE_MAC_MAX_FLOWS))
- || add_table(chain, table_hash2_create(0x1EDC6F41, TABLE_HASH_MAX_FLOWS,
+ if (add_table(chain, table_hash2_create(0x1EDC6F41, TABLE_HASH_MAX_FLOWS,
0x741B8CD7, TABLE_HASH_MAX_FLOWS))
|| add_table(chain, table_linear_create(TABLE_LINEAR_MAX_FLOWS))) {
chain_destroy(chain);
/* Functions for managing the dp interface/device. */
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/if_arp.h>
#include <linux/if_bridge.h>
else if (out_port == OFPP_CONTROLLER)
return dp_output_control(dp, skb, fwd_save_skb(skb), 0,
OFPR_ACTION);
- else if (out_port >= OFPP_MAX)
+ else if (out_port == OFPP_TABLE) {
+ struct sw_flow_key key;
+ struct sw_flow *flow;
+
+ flow_extract(skb, skb->dev->br_port->port_no, &key);
+ flow = chain_lookup(dp->chain, &key);
+ if (likely(flow != NULL)) {
+ flow_used(flow, skb);
+ execute_actions(dp, skb, &key, flow->actions, flow->n_actions);
+ return 0;
+ }
+ return -ESRCH;
+ } else if (out_port >= OFPP_MAX)
goto bad_port;
p = dp->ports[out_port];
/* FIXME: do we need to use GFP_ATOMIC everywhere here? */
-static void execute_actions(struct datapath *, struct sk_buff *,
- const struct sw_flow_key *,
- const struct ofp_action *, int n_actions);
static int make_writable(struct sk_buff **);
static struct sk_buff *retrieve_skb(uint32_t id);
max_len, OFPR_ACTION));
}
-static void execute_actions(struct datapath *dp, struct sk_buff *skb,
+void execute_actions(struct datapath *dp, struct sk_buff *skb,
const struct sw_flow_key *key,
const struct ofp_action *actions, int n_actions)
{
add_flow(struct sw_chain *chain, const struct ofp_flow_mod *ofm)
{
int error = -ENOMEM;
+ int i;
int n_acts;
struct sw_flow *flow;
goto error;
}
+ /* To prevent loops, make sure there's no action to send to the
+ * OFP_TABLE virtual port.
+ */
+ for (i=0; i<n_acts; i++) {
+ const struct ofp_action *a = &ofm->actions[i];
+
+ if (a->type == htons(OFPAT_OUTPUT)
+ && a->arg.output.port == htons(OFPP_TABLE)) {
+ /* xxx Send fancy new error message? */
+ goto error;
+ }
+ }
+
/* Allocate memory. */
flow = flow_alloc(n_acts, GFP_ATOMIC);
if (flow == NULL)
#define FORWARD_H 1
#include <linux/types.h>
+#include "datapath.h"
#include "flow.h"
struct sk_buff;
void fwd_exit(void);
+void execute_actions(struct datapath *, struct sk_buff *,
+ const struct sw_flow_key *,
+ const struct ofp_action *, int n_actions);
struct sk_buff *execute_setter(struct sk_buff *, uint16_t,
const struct sw_flow_key *, const struct ofp_action *);
export VMDIR = @VMDIR@
SHAREDFILES = ../chain.c ../crc32.c ../table-hash.c ../table-linear.c \
- ../table-mac.c ../forward.c ../flow.c ../unit-exports.c \
+ ../forward.c ../flow.c ../unit-exports.c \
../dp_dev.c ../datapath_t.c
SIMLINKFILES = $(patsubst ../%,%, $(SHAREDFILES))
../unit.c
UNIT_CFILES = $(patsubst ../%,%, $(SHARED_T_FILES))
-kFILES = ../datapath.h \
+HFILES = ../datapath.h \
../chain.h \
../crc32.h \
../flow.h \
* Distributed under the terms of the GNU GPL version 2.
*/
+#include <linux/init.h>
#include <linux/module.h>
#include "compat24.h"
* Johannes Berg <johannes@sipsolutions.net>
*/
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include_next <asm/atomic.h>
-#error "Cribbed from linux-2.6/include/asm-arm/atomic.h but untested"
-
#ifdef __KERNEL__
#if __LINUX_ARM_ARCH__ >= 6
int ret;
unsigned long flags;
- raw_local_irq_save(flags);
+ local_irq_save(flags);
ret = v->counter;
if (likely(ret == old))
v->counter = new;
- raw_local_irq_restore(flags);
+ local_irq_restore(flags);
return ret;
}
#include_next <asm/atomic.h>
#include <asm/system.h>
-#error "Cribbed from linux-2.6/include/asm-mips but not tested."
-
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#endif /* asm/atomic.h */
#include <asm/system.h>
-#error "Cribbed from linux-2.6/include/asm-mips/barrier.h but untested."
-
/* Not sure whether these really need to be defined, but the conservative
* choice seems to be to define them. */
#define CONFIG_WEAK_ORDERING 1
--- /dev/null
+#ifndef __ASM_MIPS_BREAK_H_WRAPPER
+#define __ASM_MIPS_BREAK_H_WRAPPER 1
+
+#include <linux/version.h>
+#include_next <asm/break.h>
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25)
+
+/*
+ * The following break codes are or were in use for specific purposes in
+ * other MIPS operating systems. Linux/MIPS doesn't use all of them. The
+ * unused ones are here as placeholders; we might encounter them in
+ * non-Linux/MIPS object files or make use of them in the future.
+ */
+#define BRK_USERBP 0 /* User bp (used by debuggers) */
+#define BRK_KERNELBP 1 /* Break in the kernel */
+#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */
+#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */
+#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */
+#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */
+#define BRK_OVERFLOW 6 /* Overflow check */
+#define BRK_DIVZERO 7 /* Divide by zero check */
+#define BRK_RANGE 8 /* Range error check */
+#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */
+#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */
+#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */
+#define BRK_MULOVF 1023 /* Multiply overflow */
+#define BRK_BUG 512 /* Used by BUG() */
+
+#endif /* linux kernel < 2.4.25 */
+
+#endif /* asm/break.h */
--- /dev/null
+#ifndef __ASM_MIPS_PAGE_H_WRAPPER
+#define __ASM_MIPS_PAGE_H_WRAPPER 1
+
+#include <linux/version.h>
+#include_next <asm/page.h>
+#include <asm/break.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25)
+
+#define BUG() \
+do { \
+ __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \
+} while (0)
+
+#endif /* linux kernel < 2.4.25 */
+
+#endif /* asm/page.h */
#include_next <asm/system.h>
-#error "Cribbed from linux-2.6/include/asm-mips/system.h but untested."
-
#define __HAVE_ARCH_CMPXCHG 1
static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
} else {
unsigned long flags;
- raw_local_irq_save(flags);
+ local_irq_save(flags);
retval = *m;
if (retval == old)
*m = new;
- raw_local_irq_restore(flags); /* implies memory barrier */
+ local_irq_restore(flags); /* implies memory barrier */
}
smp_llsc_mb();
} else {
unsigned long flags;
- raw_local_irq_save(flags);
+ local_irq_save(flags);
retval = *m;
if (retval == old)
*m = new;
- raw_local_irq_restore(flags); /* implies memory barrier */
+ local_irq_restore(flags); /* implies memory barrier */
}
smp_llsc_mb();
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)
#include <linux/time.h>
+#include <linux/sched.h>
#include <asm/param.h>
/*
* We define MAX_MSEC_OFFSET as the maximal value that can be accepted by
--- /dev/null
+#ifndef __LINUX_LLC_H
+#define __LINUX_LLC_H
+/*
+ * IEEE 802.2 User Interface SAPs for Linux, data structures and indicators.
+ *
+ * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#define __LLC_SOCK_SIZE__ 16 /* sizeof(sockaddr_llc), word align. */
+struct sockaddr_llc {
+ sa_family_t sllc_family; /* AF_LLC */
+ sa_family_t sllc_arphrd; /* ARPHRD_ETHER */
+ unsigned char sllc_test;
+ unsigned char sllc_xid;
+ unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */
+ unsigned char sllc_sap;
+ unsigned char sllc_mac[IFHWADDRLEN];
+ unsigned char __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 -
+ sizeof(unsigned char) * 4 - IFHWADDRLEN];
+};
+
+/* sockopt definitions. */
+enum llc_sockopts {
+ LLC_OPT_UNKNOWN = 0,
+ LLC_OPT_RETRY, /* max retrans attempts. */
+ LLC_OPT_SIZE, /* max PDU size (octets). */
+ LLC_OPT_ACK_TMR_EXP, /* ack expire time (secs). */
+ LLC_OPT_P_TMR_EXP, /* pf cycle expire time (secs). */
+ LLC_OPT_REJ_TMR_EXP, /* rej sent expire time (secs). */
+ LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */
+ LLC_OPT_TX_WIN, /* tx window size. */
+ LLC_OPT_RX_WIN, /* rx window size. */
+ LLC_OPT_MAX
+};
+
+#define LLC_OPT_MAX_RETRY 100
+#define LLC_OPT_MAX_SIZE 4196
+#define LLC_OPT_MAX_WIN 127
+#define LLC_OPT_MAX_ACK_TMR_EXP 60
+#define LLC_OPT_MAX_P_TMR_EXP 60
+#define LLC_OPT_MAX_REJ_TMR_EXP 60
+#define LLC_OPT_MAX_BUSY_TMR_EXP 60
+
+/* LLC SAP types. */
+#define LLC_SAP_NULL 0x00 /* NULL SAP. */
+#define LLC_SAP_LLC 0x02 /* LLC Sublayer Managment. */
+#define LLC_SAP_SNA 0x04 /* SNA Path Control. */
+#define LLC_SAP_PNM 0x0E /* Proway Network Managment. */
+#define LLC_SAP_IP 0x06 /* TCP/IP. */
+#define LLC_SAP_BSPAN 0x42 /* Bridge Spanning Tree Proto */
+#define LLC_SAP_MMS 0x4E /* Manufacturing Message Srv. */
+#define LLC_SAP_8208 0x7E /* ISO 8208 */
+#define LLC_SAP_3COM 0x80 /* 3COM. */
+#define LLC_SAP_PRO 0x8E /* Proway Active Station List */
+#define LLC_SAP_SNAP 0xAA /* SNAP. */
+#define LLC_SAP_BANYAN 0xBC /* Banyan. */
+#define LLC_SAP_IPX 0xE0 /* IPX/SPX. */
+#define LLC_SAP_NETBEUI 0xF0 /* NetBEUI. */
+#define LLC_SAP_LANMGR 0xF4 /* LanManager. */
+#define LLC_SAP_IMPL 0xF8 /* IMPL */
+#define LLC_SAP_DISC 0xFC /* Discovery */
+#define LLC_SAP_OSI 0xFE /* OSI Network Layers. */
+#define LLC_SAP_LAR 0xDC /* LAN Address Resolution */
+#define LLC_SAP_RM 0xD4 /* Resource Management */
+#define LLC_SAP_GLOBAL 0xFF /* Global SAP. */
+
+#ifdef __KERNEL__
+#define LLC_SAP_DYN_START 0xC0
+#define LLC_SAP_DYN_STOP 0xDE
+#define LLC_SAP_DYN_TRIES 4
+
+#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
+#endif /* __KERNEL__ */
+#endif /* __LINUX_LLC_H */
#ifndef __LINUX_MODULE_WRAPPER_H
#define __LINUX_MODULE_WRAPPER_H 1
+#include <linux/kernel.h>
#include_next <linux/module.h>
static inline int try_module_get(struct module *module)
*/
-#include <linux/types.h>
+#include <linux/init.h>
#include <linux/module.h>
+#include <linux/types.h>
#include <linux/jiffies.h>
#include <linux/random.h>
#include <linux/threads.h>
# Files shared between 2.4 and 2.6 builds
SHAREDFILES = ../chain.c ../crc32.c ../table-hash.c ../table-linear.c \
- ../table-mac.c ../forward.c ../flow.c ../unit-exports.c \
+ ../forward.c ../flow.c ../unit-exports.c \
../datapath_t.c ../dp_dev.c \
compat-2.6/genetlink.c \
compat-2.6/random32.c
+++ /dev/null
-/*
- * Distributed under the terms of the GNU GPL version 2.
- * Copyright (c) 2007, 2008 The Board of Trustees of The Leland
- * Stanford Junior University
- */
-
-#include "table.h"
-#include "crc32.h"
-#include "flow.h"
-#include "openflow.h"
-#include "datapath.h"
-
-#include <linux/slab.h>
-
-struct sw_table_mac {
- struct sw_table swt;
- spinlock_t lock;
- struct crc32 crc32;
- atomic_t n_flows;
- unsigned int max_flows;
- unsigned int bucket_mask; /* Number of buckets minus 1. */
- struct hlist_head *buckets;
-};
-
-static struct hlist_head *find_bucket(struct sw_table *swt,
- const struct sw_flow_key *key)
-{
- struct sw_table_mac *tm = (struct sw_table_mac *) swt;
- unsigned int crc = crc32_calculate(&tm->crc32, key, sizeof *key);
- return &tm->buckets[crc & tm->bucket_mask];
-}
-
-static struct sw_flow *table_mac_lookup(struct sw_table *swt,
- const struct sw_flow_key *key)
-{
- struct hlist_head *bucket = find_bucket(swt, key);
- struct hlist_node *pos;
- struct sw_flow *flow;
- hlist_for_each_entry_rcu (flow, pos, bucket, u.hnode)
- if (!memcmp(key->dl_src, flow->key.dl_src, 6))
- return flow;
- return NULL;
-}
-
-static int table_mac_insert(struct sw_table *swt, struct sw_flow *flow)
-{
- struct sw_table_mac *tm = (struct sw_table_mac *) swt;
- struct hlist_head *bucket;
- struct hlist_node *pos;
- unsigned long int flags;
- struct sw_flow *f;
-
- /* MAC table only handles flows that match on Ethernet
- source address and wildcard everything else. */
- if (likely(flow->key.wildcards != (OFPFW_ALL & ~OFPFW_DL_SRC)))
- return 0;
- bucket = find_bucket(swt, &flow->key);
-
- spin_lock_irqsave(&tm->lock, flags);
- hlist_for_each_entry_rcu (f, pos, bucket, u.hnode) {
- if (!memcmp(f->key.dl_src, flow->key.dl_src, 6)
- && flow_del(f)) {
- hlist_replace_rcu(&f->u.hnode, &flow->u.hnode);
- spin_unlock_irqrestore(&tm->lock, flags);
- flow_deferred_free(f);
- return 1;
- }
- }
-
- /* Table overflow? */
- if (atomic_read(&tm->n_flows) >= tm->max_flows) {
- spin_unlock_irqrestore(&tm->lock, flags);
- return 0;
- }
- atomic_inc(&tm->n_flows);
-
- hlist_add_head_rcu(&flow->u.hnode, bucket);
- spin_unlock_irqrestore(&tm->lock, flags);
- return 1;
-}
-
-static int do_delete(struct sw_table *swt, struct sw_flow *flow)
-{
- if (flow_del(flow)) {
- hlist_del_rcu(&flow->u.hnode);
- flow_deferred_free(flow);
- return 1;
- }
- return 0;
-}
-
-/* Returns number of deleted flows. */
-static int table_mac_delete(struct sw_table *swt,
- const struct sw_flow_key *key, int strict)
-{
- struct sw_table_mac *tm = (struct sw_table_mac *) swt;
-
- if (key->wildcards == (OFPFW_ALL & ~OFPFW_DL_SRC)) {
- struct sw_flow *flow = table_mac_lookup(swt, key);
- if (flow && do_delete(swt, flow)) {
- atomic_dec(&tm->n_flows);
- return 1;
- }
- return 0;
- } else {
- unsigned int i;
- int count = 0;
- for (i = 0; i <= tm->bucket_mask; i++) {
- struct hlist_head *bucket = &tm->buckets[i];
- struct hlist_node *pos;
- struct sw_flow *flow;
- hlist_for_each_entry_rcu (flow, pos, bucket, u.hnode)
- if (flow_del_matches(&flow->key, key, strict))
- count += do_delete(swt, flow);
- }
- if (count)
- atomic_sub(count, &tm->n_flows);
- return count;
- }
-}
-
-static int table_mac_timeout(struct datapath *dp, struct sw_table *swt)
-{
- struct sw_table_mac *tm = (struct sw_table_mac *) swt;
- unsigned int i;
- int count = 0;
-
- for (i = 0; i <= tm->bucket_mask; i++) {
- struct hlist_head *bucket = &tm->buckets[i];
- struct hlist_node *pos;
- struct sw_flow *flow;
- hlist_for_each_entry_rcu (flow, pos, bucket, u.hnode) {
- if (flow_timeout(flow)) {
- count += do_delete(swt, flow);
- if (dp->config.flags & OFPC_SEND_FLOW_EXP)
- dp_send_flow_expired(dp, flow);
- }
- }
- }
- if (count)
- atomic_sub(count, &tm->n_flows);
- return count;
-}
-
-static void table_mac_destroy(struct sw_table *swt)
-{
- struct sw_table_mac *tm = (struct sw_table_mac *) swt;
- unsigned int i;
- for (i = 0; i <= tm->bucket_mask; i++) {
- struct hlist_head *hlist = &tm->buckets[i];
- while (!hlist_empty(hlist)) {
- struct sw_flow *flow = hlist_entry(hlist->first,
- struct sw_flow, u.hnode);
- hlist_del(&flow->u.hnode);
- flow_free(flow);
- }
- }
- kfree(tm->buckets);
- kfree(tm);
-}
-
-struct swt_iterator_mac {
- struct sw_table_mac *tm;
- unsigned int bucket_i;
-};
-
-static struct sw_flow *next_head_flow(struct swt_iterator_mac *im)
-{
- for (; im->bucket_i <= im->tm->bucket_mask; im->bucket_i++) {
- struct hlist_node *first = im->tm->buckets[im->bucket_i].first;
- if (first != NULL) {
- struct sw_flow *f = hlist_entry(first,
- struct sw_flow,
- u.hnode);
- return f;
- }
- }
- return NULL;
-}
-
-static int table_mac_iterator(struct sw_table *swt,
- struct swt_iterator *swt_iter)
-{
- struct swt_iterator_mac *im;
-
- swt_iter->private = im = kmalloc(sizeof *im, GFP_KERNEL);
- if (im == NULL)
- return 0;
-
- im->tm = (struct sw_table_mac *) swt;
-
- if (atomic_read(&im->tm->n_flows) == 0)
- swt_iter->flow = NULL;
- else {
- im->bucket_i = 0;
- swt_iter->flow = next_head_flow(im);
- }
-
- return 1;
-}
-
-static void table_mac_next(struct swt_iterator *swt_iter)
-{
- struct swt_iterator_mac *im;
- struct hlist_node *next;
-
- if (swt_iter->flow == NULL)
- return;
-
- im = (struct swt_iterator_mac *) swt_iter->private;
-
- next = swt_iter->flow->u.hnode.next;
- if (next != NULL) {
- swt_iter->flow = hlist_entry(next, struct sw_flow, u.hnode);
- } else {
- im->bucket_i++;
- swt_iter->flow = next_head_flow(im);
- }
-}
-
-static void table_mac_iterator_destroy(struct swt_iterator *swt_iter)
-{
- kfree(swt_iter->private);
-}
-
-static void table_mac_stats(struct sw_table *swt, struct sw_table_stats *stats)
-{
- struct sw_table_mac *tm = (struct sw_table_mac *) swt;
- stats->name = "mac";
- stats->n_flows = atomic_read(&tm->n_flows);
- stats->max_flows = tm->max_flows;
-}
-
-struct sw_table *table_mac_create(unsigned int n_buckets,
- unsigned int max_flows)
-{
- struct sw_table_mac *tm;
- struct sw_table *swt;
-
- tm = kzalloc(sizeof *tm, GFP_KERNEL);
- if (tm == NULL)
- return NULL;
-
- BUG_ON(n_buckets & (n_buckets - 1));
-
- tm->buckets = kzalloc(n_buckets * sizeof *tm->buckets, GFP_KERNEL);
- if (tm->buckets == NULL) {
- printk("failed to allocate %u buckets\n", n_buckets);
- kfree(tm);
- return NULL;
- }
- tm->bucket_mask = n_buckets - 1;
-
- swt = &tm->swt;
- swt->lookup = table_mac_lookup;
- swt->insert = table_mac_insert;
- swt->delete = table_mac_delete;
- swt->timeout = table_mac_timeout;
- swt->destroy = table_mac_destroy;
- swt->stats = table_mac_stats;
-
- swt->iterator = table_mac_iterator;
- swt->iterator_next = table_mac_next;
- swt->iterator_destroy = table_mac_iterator_destroy;
-
- crc32_init(&tm->crc32, 0x04C11DB7); /* Ethernet CRC. */
- atomic_set(&tm->n_flows, 0);
- tm->max_flows = max_flows;
- spin_lock_init(&tm->lock);
-
- return swt;
-}
void (*stats)(struct sw_table *table, struct sw_table_stats *stats);
};
-struct sw_table *table_mac_create(unsigned int n_buckets,
- unsigned int max_flows);
struct sw_table *table_hash_create(unsigned int polynomial,
unsigned int n_buckets);
struct sw_table *table_hash2_create(unsigned int poly0, unsigned int buckets0,
void run_table_t(void)
{
- int mac_buckets, mac_max, linear_max, hash_buckets, hash2_buckets1;
+ int linear_max, hash_buckets, hash2_buckets1;
int hash2_buckets2, num_flows, num_iterations;
int i;
struct sw_table *swt;
/* Most basic operations. */
- simple_insert_delete(table_mac_create(2048, 65536),
- OFPFW_ALL & ~OFPFW_DL_SRC);
simple_insert_delete(table_linear_create(2048), 0);
simple_insert_delete(table_hash_create(0x04C11DB7, 2048), 0);
simple_insert_delete(table_hash2_create(0x04C11DB7, 2048,
0x1EDC6F41, 2048), 0);
- /* MAC table operations. */
- multiple_insert_destroy(table_mac_create(2048, 65536), 1024,
- OFPFW_ALL & ~OFPFW_DL_SRC, 0, 0);
- multiple_insert_destroy(table_mac_create(2048, 65536), 2048,
- OFPFW_ALL & ~OFPFW_DL_SRC, 0, 0);
- multiple_insert_destroy(table_mac_create(2048, 65536), 65535,
- OFPFW_ALL & ~OFPFW_DL_SRC, 0, 0);
- multiple_insert_destroy(table_mac_create(2048, 65536),
- 131072, OFPFW_ALL & ~OFPFW_DL_SRC, 65536, 65536);
-
/* Linear table operations. */
multiple_insert_destroy(table_linear_create(2048), 1024, 0, 0, 0);
multiple_insert_destroy(table_linear_create(2048), 2048, 0, 0, 0);
multiple_insert_destroy(table_hash2_create(0x04C11DB7, 1<<20,
0x04C11DB7, 1<<20), 1<<16, 0, 0, 100);
- mac_buckets = 1024;
- mac_max = 2048;
linear_max = 2048;
hash_buckets = 2048;
hash2_buckets1 = 1024;
printk(" complex_add_delete_test with %d flows and %d iterations\n\n",
num_flows, num_iterations);
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 3; i++) {
unsigned int mask = i == 0 ? : 0;
if (unit_failed())
mask = 0;
switch (i) {
case 0:
- swt = table_mac_create(mac_buckets, mac_max);
- mask = OFPFW_ALL & ~OFPFW_DL_SRC;
- break;
- case 1:
swt = table_linear_create(linear_max);
break;
- case 2:
+ case 1:
swt = table_hash_create (0x04C11DB7, hash_buckets);
break;
- case 3:
+ case 2:
swt = table_hash2_create(0x04C11DB7, hash2_buckets1,
0x1EDC6F41, hash2_buckets2);
break;
return;
}
printk("Testing %s table with %d buckets and %d max flows...\n",
- table_name(swt), mac_buckets, mac_max);
+ table_name(swt), hash_buckets, num_flows);
iterator_test(swt, 0, mask);
iterator_test(swt, num_flows, mask);
add_test(swt, mask);
EXPORT_SYMBOL(flow_free);
EXPORT_SYMBOL(flow_cache);
-EXPORT_SYMBOL(table_mac_create);
EXPORT_SYMBOL(table_hash_create);
EXPORT_SYMBOL(table_hash2_create);
EXPORT_SYMBOL(table_linear_create);
*/
#include <linux/autoconf.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/version.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/socket.h>
+#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/genetlink.h>
#include <linux/version.h>
#ifndef OPENFLOW_NETLINK_H
#define OPENFLOW_NETLINK_H 1
+#include <linux/types.h>
#include <linux/netlink.h>
#define DP_GENL_FAMILY_NAME "OpenFlow"
OFPP_MAX = 0x100,
/* Fake output "ports". */
- OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching */
+ OFPP_TABLE = 0xfff9, /* Perform actions in flow table.
+ * NB: This can only be the destination
+ * port for packet-out messages.
+ */
+ OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching. */
OFPP_FLOOD = 0xfffb, /* All physical ports except input port and
those disabled by STP. */
OFPP_ALL = 0xfffc, /* All physical ports except input port. */
goto error_free_pid;
}
+#ifdef NETLINK_ADD_MEMBERSHIP
/* This method of joining multicast groups is only supported by newish
* kernels, but it allows for an arbitrary number of multicast groups. */
if (multicast_group > 32
multicast_group, strerror(errno));
goto error_free_pid;
}
+#endif
*sockp = sock;
return 0;