diff options
author | Pravin B Shelar <pshelar@nicira.com> | 2012-08-23 15:40:54 -0400 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2012-09-03 22:20:49 -0400 |
commit | 15eac2a74277bc7de68a7c2a64a7c91b4b6f5961 (patch) | |
tree | cbe59331108927c14a1930a6303ffbb2b303b9a7 | |
parent | 46df7b814548849deee01f50bc75f8f5ae8cd767 (diff) |
openvswitch: Increase maximum number of datapath ports.
Use hash table to store ports of datapath. Allow 64K ports per switch.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
-rw-r--r-- | net/openvswitch/actions.c | 2 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 110 | ||||
-rw-r--r-- | net/openvswitch/datapath.h | 33 | ||||
-rw-r--r-- | net/openvswitch/flow.c | 11 | ||||
-rw-r--r-- | net/openvswitch/flow.h | 3 | ||||
-rw-r--r-- | net/openvswitch/vport.c | 1 | ||||
-rw-r--r-- | net/openvswitch/vport.h | 4 |
7 files changed, 113 insertions, 51 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index f3f96badf5aa..0da687769f56 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -266,7 +266,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port) | |||
266 | if (unlikely(!skb)) | 266 | if (unlikely(!skb)) |
267 | return -ENOMEM; | 267 | return -ENOMEM; |
268 | 268 | ||
269 | vport = rcu_dereference(dp->ports[out_port]); | 269 | vport = ovs_vport_rcu(dp, out_port); |
270 | if (unlikely(!vport)) { | 270 | if (unlikely(!vport)) { |
271 | kfree_skb(skb); | 271 | kfree_skb(skb); |
272 | return -ENODEV; | 272 | return -ENODEV; |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index cad39fca75a9..105a0b5adc51 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -116,7 +116,7 @@ static struct datapath *get_dp(struct net *net, int dp_ifindex) | |||
116 | /* Must be called with rcu_read_lock or RTNL lock. */ | 116 | /* Must be called with rcu_read_lock or RTNL lock. */ |
117 | const char *ovs_dp_name(const struct datapath *dp) | 117 | const char *ovs_dp_name(const struct datapath *dp) |
118 | { | 118 | { |
119 | struct vport *vport = rcu_dereference_rtnl(dp->ports[OVSP_LOCAL]); | 119 | struct vport *vport = ovs_vport_rtnl_rcu(dp, OVSP_LOCAL); |
120 | return vport->ops->get_name(vport); | 120 | return vport->ops->get_name(vport); |
121 | } | 121 | } |
122 | 122 | ||
@@ -127,7 +127,7 @@ static int get_dpifindex(struct datapath *dp) | |||
127 | 127 | ||
128 | rcu_read_lock(); | 128 | rcu_read_lock(); |
129 | 129 | ||
130 | local = rcu_dereference(dp->ports[OVSP_LOCAL]); | 130 | local = ovs_vport_rcu(dp, OVSP_LOCAL); |
131 | if (local) | 131 | if (local) |
132 | ifindex = local->ops->get_ifindex(local); | 132 | ifindex = local->ops->get_ifindex(local); |
133 | else | 133 | else |
@@ -145,9 +145,30 @@ static void destroy_dp_rcu(struct rcu_head *rcu) | |||
145 | ovs_flow_tbl_destroy((__force struct flow_table *)dp->table); | 145 | ovs_flow_tbl_destroy((__force struct flow_table *)dp->table); |
146 | free_percpu(dp->stats_percpu); | 146 | free_percpu(dp->stats_percpu); |
147 | release_net(ovs_dp_get_net(dp)); | 147 | release_net(ovs_dp_get_net(dp)); |
148 | kfree(dp->ports); | ||
148 | kfree(dp); | 149 | kfree(dp); |
149 | } | 150 | } |
150 | 151 | ||
152 | static struct hlist_head *vport_hash_bucket(const struct datapath *dp, | ||
153 | u16 port_no) | ||
154 | { | ||
155 | return &dp->ports[port_no & (DP_VPORT_HASH_BUCKETS - 1)]; | ||
156 | } | ||
157 | |||
158 | struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no) | ||
159 | { | ||
160 | struct vport *vport; | ||
161 | struct hlist_node *n; | ||
162 | struct hlist_head *head; | ||
163 | |||
164 | head = vport_hash_bucket(dp, port_no); | ||
165 | hlist_for_each_entry_rcu(vport, n, head, dp_hash_node) { | ||
166 | if (vport->port_no == port_no) | ||
167 | return vport; | ||
168 | } | ||
169 | return NULL; | ||
170 | } | ||
171 | |||
151 | /* Called with RTNL lock and genl_lock. */ | 172 | /* Called with RTNL lock and genl_lock. */ |
152 | static struct vport *new_vport(const struct vport_parms *parms) | 173 | static struct vport *new_vport(const struct vport_parms *parms) |
153 | { | 174 | { |
@@ -156,9 +177,9 @@ static struct vport *new_vport(const struct vport_parms *parms) | |||
156 | vport = ovs_vport_add(parms); | 177 | vport = ovs_vport_add(parms); |
157 | if (!IS_ERR(vport)) { | 178 | if (!IS_ERR(vport)) { |
158 | struct datapath *dp = parms->dp; | 179 | struct datapath *dp = parms->dp; |
180 | struct hlist_head *head = vport_hash_bucket(dp, vport->port_no); | ||
159 | 181 | ||
160 | rcu_assign_pointer(dp->ports[parms->port_no], vport); | 182 | hlist_add_head_rcu(&vport->dp_hash_node, head); |
161 | list_add(&vport->node, &dp->port_list); | ||
162 | } | 183 | } |
163 | 184 | ||
164 | return vport; | 185 | return vport; |
@@ -170,8 +191,7 @@ void ovs_dp_detach_port(struct vport *p) | |||
170 | ASSERT_RTNL(); | 191 | ASSERT_RTNL(); |
171 | 192 | ||
172 | /* First drop references to device. */ | 193 | /* First drop references to device. */ |
173 | list_del(&p->node); | 194 | hlist_del_rcu(&p->dp_hash_node); |
174 | rcu_assign_pointer(p->dp->ports[p->port_no], NULL); | ||
175 | 195 | ||
176 | /* Then destroy it. */ | 196 | /* Then destroy it. */ |
177 | ovs_vport_del(p); | 197 | ovs_vport_del(p); |
@@ -1248,7 +1268,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1248 | struct datapath *dp; | 1268 | struct datapath *dp; |
1249 | struct vport *vport; | 1269 | struct vport *vport; |
1250 | struct ovs_net *ovs_net; | 1270 | struct ovs_net *ovs_net; |
1251 | int err; | 1271 | int err, i; |
1252 | 1272 | ||
1253 | err = -EINVAL; | 1273 | err = -EINVAL; |
1254 | if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID]) | 1274 | if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID]) |
@@ -1261,7 +1281,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1261 | if (dp == NULL) | 1281 | if (dp == NULL) |
1262 | goto err_unlock_rtnl; | 1282 | goto err_unlock_rtnl; |
1263 | 1283 | ||
1264 | INIT_LIST_HEAD(&dp->port_list); | ||
1265 | ovs_dp_set_net(dp, hold_net(sock_net(skb->sk))); | 1284 | ovs_dp_set_net(dp, hold_net(sock_net(skb->sk))); |
1266 | 1285 | ||
1267 | /* Allocate table. */ | 1286 | /* Allocate table. */ |
@@ -1276,6 +1295,16 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1276 | goto err_destroy_table; | 1295 | goto err_destroy_table; |
1277 | } | 1296 | } |
1278 | 1297 | ||
1298 | dp->ports = kmalloc(DP_VPORT_HASH_BUCKETS * sizeof(struct hlist_head), | ||
1299 | GFP_KERNEL); | ||
1300 | if (!dp->ports) { | ||
1301 | err = -ENOMEM; | ||
1302 | goto err_destroy_percpu; | ||
1303 | } | ||
1304 | |||
1305 | for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) | ||
1306 | INIT_HLIST_HEAD(&dp->ports[i]); | ||
1307 | |||
1279 | /* Set up our datapath device. */ | 1308 | /* Set up our datapath device. */ |
1280 | parms.name = nla_data(a[OVS_DP_ATTR_NAME]); | 1309 | parms.name = nla_data(a[OVS_DP_ATTR_NAME]); |
1281 | parms.type = OVS_VPORT_TYPE_INTERNAL; | 1310 | parms.type = OVS_VPORT_TYPE_INTERNAL; |
@@ -1290,7 +1319,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1290 | if (err == -EBUSY) | 1319 | if (err == -EBUSY) |
1291 | err = -EEXIST; | 1320 | err = -EEXIST; |
1292 | 1321 | ||
1293 | goto err_destroy_percpu; | 1322 | goto err_destroy_ports_array; |
1294 | } | 1323 | } |
1295 | 1324 | ||
1296 | reply = ovs_dp_cmd_build_info(dp, info->snd_pid, | 1325 | reply = ovs_dp_cmd_build_info(dp, info->snd_pid, |
@@ -1309,7 +1338,9 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1309 | return 0; | 1338 | return 0; |
1310 | 1339 | ||
1311 | err_destroy_local_port: | 1340 | err_destroy_local_port: |
1312 | ovs_dp_detach_port(rtnl_dereference(dp->ports[OVSP_LOCAL])); | 1341 | ovs_dp_detach_port(ovs_vport_rtnl(dp, OVSP_LOCAL)); |
1342 | err_destroy_ports_array: | ||
1343 | kfree(dp->ports); | ||
1313 | err_destroy_percpu: | 1344 | err_destroy_percpu: |
1314 | free_percpu(dp->stats_percpu); | 1345 | free_percpu(dp->stats_percpu); |
1315 | err_destroy_table: | 1346 | err_destroy_table: |
@@ -1326,15 +1357,21 @@ err: | |||
1326 | /* Called with genl_mutex. */ | 1357 | /* Called with genl_mutex. */ |
1327 | static void __dp_destroy(struct datapath *dp) | 1358 | static void __dp_destroy(struct datapath *dp) |
1328 | { | 1359 | { |
1329 | struct vport *vport, *next_vport; | 1360 | int i; |
1330 | 1361 | ||
1331 | rtnl_lock(); | 1362 | rtnl_lock(); |
1332 | list_for_each_entry_safe(vport, next_vport, &dp->port_list, node) | 1363 | |
1333 | if (vport->port_no != OVSP_LOCAL) | 1364 | for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) { |
1334 | ovs_dp_detach_port(vport); | 1365 | struct vport *vport; |
1366 | struct hlist_node *node, *n; | ||
1367 | |||
1368 | hlist_for_each_entry_safe(vport, node, n, &dp->ports[i], dp_hash_node) | ||
1369 | if (vport->port_no != OVSP_LOCAL) | ||
1370 | ovs_dp_detach_port(vport); | ||
1371 | } | ||
1335 | 1372 | ||
1336 | list_del(&dp->list_node); | 1373 | list_del(&dp->list_node); |
1337 | ovs_dp_detach_port(rtnl_dereference(dp->ports[OVSP_LOCAL])); | 1374 | ovs_dp_detach_port(ovs_vport_rtnl(dp, OVSP_LOCAL)); |
1338 | 1375 | ||
1339 | /* rtnl_unlock() will wait until all the references to devices that | 1376 | /* rtnl_unlock() will wait until all the references to devices that |
1340 | * are pending unregistration have been dropped. We do it here to | 1377 | * are pending unregistration have been dropped. We do it here to |
@@ -1566,7 +1603,7 @@ static struct vport *lookup_vport(struct net *net, | |||
1566 | if (!dp) | 1603 | if (!dp) |
1567 | return ERR_PTR(-ENODEV); | 1604 | return ERR_PTR(-ENODEV); |
1568 | 1605 | ||
1569 | vport = rcu_dereference_rtnl(dp->ports[port_no]); | 1606 | vport = ovs_vport_rtnl_rcu(dp, port_no); |
1570 | if (!vport) | 1607 | if (!vport) |
1571 | return ERR_PTR(-ENOENT); | 1608 | return ERR_PTR(-ENOENT); |
1572 | return vport; | 1609 | return vport; |
@@ -1603,7 +1640,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1603 | if (port_no >= DP_MAX_PORTS) | 1640 | if (port_no >= DP_MAX_PORTS) |
1604 | goto exit_unlock; | 1641 | goto exit_unlock; |
1605 | 1642 | ||
1606 | vport = rtnl_dereference(dp->ports[port_no]); | 1643 | vport = ovs_vport_rtnl_rcu(dp, port_no); |
1607 | err = -EBUSY; | 1644 | err = -EBUSY; |
1608 | if (vport) | 1645 | if (vport) |
1609 | goto exit_unlock; | 1646 | goto exit_unlock; |
@@ -1613,7 +1650,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1613 | err = -EFBIG; | 1650 | err = -EFBIG; |
1614 | goto exit_unlock; | 1651 | goto exit_unlock; |
1615 | } | 1652 | } |
1616 | vport = rtnl_dereference(dp->ports[port_no]); | 1653 | vport = ovs_vport_rtnl(dp, port_no); |
1617 | if (!vport) | 1654 | if (!vport) |
1618 | break; | 1655 | break; |
1619 | } | 1656 | } |
@@ -1755,32 +1792,39 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1755 | { | 1792 | { |
1756 | struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh)); | 1793 | struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh)); |
1757 | struct datapath *dp; | 1794 | struct datapath *dp; |
1758 | u32 port_no; | 1795 | int bucket = cb->args[0], skip = cb->args[1]; |
1759 | int retval; | 1796 | int i, j = 0; |
1760 | 1797 | ||
1761 | dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); | 1798 | dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); |
1762 | if (!dp) | 1799 | if (!dp) |
1763 | return -ENODEV; | 1800 | return -ENODEV; |
1764 | 1801 | ||
1765 | rcu_read_lock(); | 1802 | rcu_read_lock(); |
1766 | for (port_no = cb->args[0]; port_no < DP_MAX_PORTS; port_no++) { | 1803 | for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) { |
1767 | struct vport *vport; | 1804 | struct vport *vport; |
1768 | 1805 | struct hlist_node *n; | |
1769 | vport = rcu_dereference(dp->ports[port_no]); | 1806 | |
1770 | if (!vport) | 1807 | j = 0; |
1771 | continue; | 1808 | hlist_for_each_entry_rcu(vport, n, &dp->ports[i], dp_hash_node) { |
1772 | 1809 | if (j >= skip && | |
1773 | if (ovs_vport_cmd_fill_info(vport, skb, NETLINK_CB(cb->skb).pid, | 1810 | ovs_vport_cmd_fill_info(vport, skb, |
1774 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1811 | NETLINK_CB(cb->skb).pid, |
1775 | OVS_VPORT_CMD_NEW) < 0) | 1812 | cb->nlh->nlmsg_seq, |
1776 | break; | 1813 | NLM_F_MULTI, |
1814 | OVS_VPORT_CMD_NEW) < 0) | ||
1815 | goto out; | ||
1816 | |||
1817 | j++; | ||
1818 | } | ||
1819 | skip = 0; | ||
1777 | } | 1820 | } |
1821 | out: | ||
1778 | rcu_read_unlock(); | 1822 | rcu_read_unlock(); |
1779 | 1823 | ||
1780 | cb->args[0] = port_no; | 1824 | cb->args[0] = i; |
1781 | retval = skb->len; | 1825 | cb->args[1] = j; |
1782 | 1826 | ||
1783 | return retval; | 1827 | return skb->len; |
1784 | } | 1828 | } |
1785 | 1829 | ||
1786 | static struct genl_ops dp_vport_genl_ops[] = { | 1830 | static struct genl_ops dp_vport_genl_ops[] = { |
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 771c11e13e34..129ec5480758 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h | |||
@@ -29,7 +29,9 @@ | |||
29 | #include "flow.h" | 29 | #include "flow.h" |
30 | #include "vport.h" | 30 | #include "vport.h" |
31 | 31 | ||
32 | #define DP_MAX_PORTS 1024 | 32 | #define DP_MAX_PORTS USHRT_MAX |
33 | #define DP_VPORT_HASH_BUCKETS 1024 | ||
34 | |||
33 | #define SAMPLE_ACTION_DEPTH 3 | 35 | #define SAMPLE_ACTION_DEPTH 3 |
34 | 36 | ||
35 | /** | 37 | /** |
@@ -57,10 +59,8 @@ struct dp_stats_percpu { | |||
57 | * @list_node: Element in global 'dps' list. | 59 | * @list_node: Element in global 'dps' list. |
58 | * @n_flows: Number of flows currently in flow table. | 60 | * @n_flows: Number of flows currently in flow table. |
59 | * @table: Current flow table. Protected by genl_lock and RCU. | 61 | * @table: Current flow table. Protected by genl_lock and RCU. |
60 | * @ports: Map from port number to &struct vport. %OVSP_LOCAL port | 62 | * @ports: Hash table for ports. %OVSP_LOCAL port always exists. Protected by |
61 | * always exists, other ports may be %NULL. Protected by RTNL and RCU. | 63 | * RTNL and RCU. |
62 | * @port_list: List of all ports in @ports in arbitrary order. RTNL required | ||
63 | * to iterate or modify. | ||
64 | * @stats_percpu: Per-CPU datapath statistics. | 64 | * @stats_percpu: Per-CPU datapath statistics. |
65 | * @net: Reference to net namespace. | 65 | * @net: Reference to net namespace. |
66 | * | 66 | * |
@@ -75,8 +75,7 @@ struct datapath { | |||
75 | struct flow_table __rcu *table; | 75 | struct flow_table __rcu *table; |
76 | 76 | ||
77 | /* Switch ports. */ | 77 | /* Switch ports. */ |
78 | struct vport __rcu *ports[DP_MAX_PORTS]; | 78 | struct hlist_head *ports; |
79 | struct list_head port_list; | ||
80 | 79 | ||
81 | /* Stats. */ | 80 | /* Stats. */ |
82 | struct dp_stats_percpu __percpu *stats_percpu; | 81 | struct dp_stats_percpu __percpu *stats_percpu; |
@@ -87,6 +86,26 @@ struct datapath { | |||
87 | #endif | 86 | #endif |
88 | }; | 87 | }; |
89 | 88 | ||
89 | struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no); | ||
90 | |||
91 | static inline struct vport *ovs_vport_rcu(const struct datapath *dp, int port_no) | ||
92 | { | ||
93 | WARN_ON_ONCE(!rcu_read_lock_held()); | ||
94 | return ovs_lookup_vport(dp, port_no); | ||
95 | } | ||
96 | |||
97 | static inline struct vport *ovs_vport_rtnl_rcu(const struct datapath *dp, int port_no) | ||
98 | { | ||
99 | WARN_ON_ONCE(!rcu_read_lock_held() && !rtnl_is_locked()); | ||
100 | return ovs_lookup_vport(dp, port_no); | ||
101 | } | ||
102 | |||
103 | static inline struct vport *ovs_vport_rtnl(const struct datapath *dp, int port_no) | ||
104 | { | ||
105 | ASSERT_RTNL(); | ||
106 | return ovs_lookup_vport(dp, port_no); | ||
107 | } | ||
108 | |||
90 | /** | 109 | /** |
91 | * struct ovs_skb_cb - OVS data in skb CB | 110 | * struct ovs_skb_cb - OVS data in skb CB |
92 | * @flow: The flow associated with this packet. May be %NULL if no flow. | 111 | * @flow: The flow associated with this packet. May be %NULL if no flow. |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index b7f38b161909..f9f211d95ebe 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions) | |||
203 | int actions_len = nla_len(actions); | 203 | int actions_len = nla_len(actions); |
204 | struct sw_flow_actions *sfa; | 204 | struct sw_flow_actions *sfa; |
205 | 205 | ||
206 | /* At least DP_MAX_PORTS actions are required to be able to flood a | 206 | if (actions_len > MAX_ACTIONS_BUFSIZE) |
207 | * packet to every port. Factor of 2 allows for setting VLAN tags, | ||
208 | * etc. */ | ||
209 | if (actions_len > 2 * DP_MAX_PORTS * nla_total_size(4)) | ||
210 | return ERR_PTR(-EINVAL); | 207 | return ERR_PTR(-EINVAL); |
211 | 208 | ||
212 | sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL); | 209 | sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL); |
@@ -1000,7 +997,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1000 | swkey->phy.in_port = in_port; | 997 | swkey->phy.in_port = in_port; |
1001 | attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT); | 998 | attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT); |
1002 | } else { | 999 | } else { |
1003 | swkey->phy.in_port = USHRT_MAX; | 1000 | swkey->phy.in_port = DP_MAX_PORTS; |
1004 | } | 1001 | } |
1005 | 1002 | ||
1006 | /* Data attributes. */ | 1003 | /* Data attributes. */ |
@@ -1143,7 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | |||
1143 | const struct nlattr *nla; | 1140 | const struct nlattr *nla; |
1144 | int rem; | 1141 | int rem; |
1145 | 1142 | ||
1146 | *in_port = USHRT_MAX; | 1143 | *in_port = DP_MAX_PORTS; |
1147 | *priority = 0; | 1144 | *priority = 0; |
1148 | 1145 | ||
1149 | nla_for_each_nested(nla, attr, rem) { | 1146 | nla_for_each_nested(nla, attr, rem) { |
@@ -1180,7 +1177,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1180 | nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) | 1177 | nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) |
1181 | goto nla_put_failure; | 1178 | goto nla_put_failure; |
1182 | 1179 | ||
1183 | if (swkey->phy.in_port != USHRT_MAX && | 1180 | if (swkey->phy.in_port != DP_MAX_PORTS && |
1184 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) | 1181 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) |
1185 | goto nla_put_failure; | 1182 | goto nla_put_failure; |
1186 | 1183 | ||
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 9b75617ca4e0..d92e22a638cf 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
@@ -43,7 +43,7 @@ struct sw_flow_actions { | |||
43 | struct sw_flow_key { | 43 | struct sw_flow_key { |
44 | struct { | 44 | struct { |
45 | u32 priority; /* Packet QoS priority. */ | 45 | u32 priority; /* Packet QoS priority. */ |
46 | u16 in_port; /* Input switch port (or USHRT_MAX). */ | 46 | u16 in_port; /* Input switch port (or DP_MAX_PORTS). */ |
47 | } phy; | 47 | } phy; |
48 | struct { | 48 | struct { |
49 | u8 src[ETH_ALEN]; /* Ethernet source address. */ | 49 | u8 src[ETH_ALEN]; /* Ethernet source address. */ |
@@ -161,6 +161,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
161 | int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | 161 | int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, |
162 | const struct nlattr *); | 162 | const struct nlattr *); |
163 | 163 | ||
164 | #define MAX_ACTIONS_BUFSIZE (16 * 1024) | ||
164 | #define TBL_MIN_BUCKETS 1024 | 165 | #define TBL_MIN_BUCKETS 1024 |
165 | 166 | ||
166 | struct flow_table { | 167 | struct flow_table { |
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 9873acea9785..1abd9609ba78 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -127,6 +127,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops, | |||
127 | vport->port_no = parms->port_no; | 127 | vport->port_no = parms->port_no; |
128 | vport->upcall_pid = parms->upcall_pid; | 128 | vport->upcall_pid = parms->upcall_pid; |
129 | vport->ops = ops; | 129 | vport->ops = ops; |
130 | INIT_HLIST_NODE(&vport->dp_hash_node); | ||
130 | 131 | ||
131 | vport->percpu_stats = alloc_percpu(struct vport_percpu_stats); | 132 | vport->percpu_stats = alloc_percpu(struct vport_percpu_stats); |
132 | if (!vport->percpu_stats) { | 133 | if (!vport->percpu_stats) { |
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index 97cef08d981b..c56e4836e93b 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h | |||
@@ -70,10 +70,10 @@ struct vport_err_stats { | |||
70 | * @rcu: RCU callback head for deferred destruction. | 70 | * @rcu: RCU callback head for deferred destruction. |
71 | * @port_no: Index into @dp's @ports array. | 71 | * @port_no: Index into @dp's @ports array. |
72 | * @dp: Datapath to which this port belongs. | 72 | * @dp: Datapath to which this port belongs. |
73 | * @node: Element in @dp's @port_list. | ||
74 | * @upcall_pid: The Netlink port to use for packets received on this port that | 73 | * @upcall_pid: The Netlink port to use for packets received on this port that |
75 | * miss the flow table. | 74 | * miss the flow table. |
76 | * @hash_node: Element in @dev_table hash table in vport.c. | 75 | * @hash_node: Element in @dev_table hash table in vport.c. |
76 | * @dp_hash_node: Element in @datapath->ports hash table in datapath.c. | ||
77 | * @ops: Class structure. | 77 | * @ops: Class structure. |
78 | * @percpu_stats: Points to per-CPU statistics used and maintained by vport | 78 | * @percpu_stats: Points to per-CPU statistics used and maintained by vport |
79 | * @stats_lock: Protects @err_stats; | 79 | * @stats_lock: Protects @err_stats; |
@@ -83,10 +83,10 @@ struct vport { | |||
83 | struct rcu_head rcu; | 83 | struct rcu_head rcu; |
84 | u16 port_no; | 84 | u16 port_no; |
85 | struct datapath *dp; | 85 | struct datapath *dp; |
86 | struct list_head node; | ||
87 | u32 upcall_pid; | 86 | u32 upcall_pid; |
88 | 87 | ||
89 | struct hlist_node hash_node; | 88 | struct hlist_node hash_node; |
89 | struct hlist_node dp_hash_node; | ||
90 | const struct vport_ops *ops; | 90 | const struct vport_ops *ops; |
91 | 91 | ||
92 | struct vport_percpu_stats __percpu *percpu_stats; | 92 | struct vport_percpu_stats __percpu *percpu_stats; |