X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=e9a4e189464bd9062ae3c83bf4c64e26209e266d;hb=fe4a02e4fa6be030a0478f6b01b0d4b6ab9b808f;hp=754cb32ffc677fd4c54d99f5041d913a845a653e;hpb=16d650e5a47cd0aa0430ab252330f0e66f3420c6;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 754cb32f..e9a4e189 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira Networks. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -60,10 +60,14 @@ #include "vport-internal_dev.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \ - LINUX_VERSION_CODE > KERNEL_VERSION(3,2,0) + LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0) #error Kernels before 2.6.18 or after 3.2 are not supported by this version of Open vSwitch. #endif +#define REHASH_FLOW_INTERVAL (10 * 60 * HZ) +static void rehash_flow_table(struct work_struct *work); +static DECLARE_DELAYED_WORK(rehash_flow_wq, rehash_flow_table); + int (*ovs_dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd); EXPORT_SYMBOL(ovs_dp_ioctl_hook); @@ -1546,9 +1550,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) int i = 0; list_for_each_entry(dp, &dps, list_node) { - if (i < skip) - continue; - if (ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).pid, + if (i >= skip && + ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, OVS_DP_CMD_NEW) < 0) break; @@ -2040,6 +2043,29 @@ error: return err; } +static int __rehash_flow_table(void *dummy) +{ + struct datapath *dp; + + list_for_each_entry(dp, &dps, list_node) { + struct flow_table *old_table = genl_dereference(dp->table); + struct flow_table *new_table; + + new_table = ovs_flow_tbl_rehash(old_table); + if (!IS_ERR(new_table)) { + rcu_assign_pointer(dp->table, new_table); + ovs_flow_tbl_deferred_destroy(old_table); + } + } + return 0; +} + +static void rehash_flow_table(struct work_struct *work) +{ + genl_exec(__rehash_flow_table, NULL); + schedule_delayed_work(&rehash_flow_wq, REHASH_FLOW_INTERVAL); +} + static int __init dp_init(void) { struct sk_buff *dummy_skb; @@ -2078,6 +2104,8 @@ static int __init dp_init(void) if (err < 0) goto error_unreg_notifier; + schedule_delayed_work(&rehash_flow_wq, REHASH_FLOW_INTERVAL); + return 0; error_unreg_notifier: @@ -2098,6 +2126,7 @@ error: static void dp_cleanup(void) { + cancel_delayed_work_sync(&rehash_flow_wq); rcu_barrier(); dp_unregister_genl(ARRAY_SIZE(dp_genl_families)); unregister_netdevice_notifier(&ovs_dp_device_notifier);