Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
cefd81cf
Commit
cefd81cf
authored
Sep 04, 2012
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch
parents
3731a334
15eac2a7
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
317 additions
and
171 deletions
+317
-171
net/openvswitch/actions.c
net/openvswitch/actions.c
+1
-1
net/openvswitch/datapath.c
net/openvswitch/datapath.c
+237
-138
net/openvswitch/datapath.h
net/openvswitch/datapath.h
+42
-8
net/openvswitch/dp_notify.c
net/openvswitch/dp_notify.c
+5
-3
net/openvswitch/flow.c
net/openvswitch/flow.c
+4
-7
net/openvswitch/flow.h
net/openvswitch/flow.h
+2
-1
net/openvswitch/vport-internal_dev.c
net/openvswitch/vport-internal_dev.c
+6
-1
net/openvswitch/vport-netdev.c
net/openvswitch/vport-netdev.c
+1
-1
net/openvswitch/vport.c
net/openvswitch/vport.c
+15
-8
net/openvswitch/vport.h
net/openvswitch/vport.h
+4
-3
No files found.
net/openvswitch/actions.c
View file @
cefd81cf
...
@@ -266,7 +266,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
...
@@ -266,7 +266,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
if
(
unlikely
(
!
skb
))
if
(
unlikely
(
!
skb
))
return
-
ENOMEM
;
return
-
ENOMEM
;
vport
=
rcu_dereference
(
dp
->
ports
[
out_port
]
);
vport
=
ovs_vport_rcu
(
dp
,
out_port
);
if
(
unlikely
(
!
vport
))
{
if
(
unlikely
(
!
vport
))
{
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
ENODEV
;
return
-
ENODEV
;
...
...
net/openvswitch/datapath.c
View file @
cefd81cf
This diff is collapsed.
Click to expand it.
net/openvswitch/datapath.h
View file @
cefd81cf
...
@@ -27,10 +27,11 @@
...
@@ -27,10 +27,11 @@
#include <linux/u64_stats_sync.h>
#include <linux/u64_stats_sync.h>
#include "flow.h"
#include "flow.h"
#include "vport.h"
struct
vport
;
#define DP_MAX_PORTS USHRT_MAX
#define DP_VPORT_HASH_BUCKETS 1024
#define DP_MAX_PORTS 1024
#define SAMPLE_ACTION_DEPTH 3
#define SAMPLE_ACTION_DEPTH 3
/**
/**
...
@@ -58,11 +59,10 @@ struct dp_stats_percpu {
...
@@ -58,11 +59,10 @@ struct dp_stats_percpu {
* @list_node: Element in global 'dps' list.
* @list_node: Element in global 'dps' list.
* @n_flows: Number of flows currently in flow table.
* @n_flows: Number of flows currently in flow table.
* @table: Current flow table. Protected by genl_lock and RCU.
* @table: Current flow table. Protected by genl_lock and RCU.
* @ports: Map from port number to &struct vport. %OVSP_LOCAL port
* @ports: Hash table for ports. %OVSP_LOCAL port always exists. Protected by
* always exists, other ports may be %NULL. Protected by RTNL and RCU.
* RTNL and RCU.
* @port_list: List of all ports in @ports in arbitrary order. RTNL required
* to iterate or modify.
* @stats_percpu: Per-CPU datapath statistics.
* @stats_percpu: Per-CPU datapath statistics.
* @net: Reference to net namespace.
*
*
* Context: See the comment on locking at the top of datapath.c for additional
* Context: See the comment on locking at the top of datapath.c for additional
* locking information.
* locking information.
...
@@ -75,13 +75,37 @@ struct datapath {
...
@@ -75,13 +75,37 @@ struct datapath {
struct
flow_table
__rcu
*
table
;
struct
flow_table
__rcu
*
table
;
/* Switch ports. */
/* Switch ports. */
struct
vport
__rcu
*
ports
[
DP_MAX_PORTS
];
struct
hlist_head
*
ports
;
struct
list_head
port_list
;
/* Stats. */
/* Stats. */
struct
dp_stats_percpu
__percpu
*
stats_percpu
;
struct
dp_stats_percpu
__percpu
*
stats_percpu
;
#ifdef CONFIG_NET_NS
/* Network namespace ref. */
struct
net
*
net
;
#endif
};
};
struct
vport
*
ovs_lookup_vport
(
const
struct
datapath
*
dp
,
u16
port_no
);
static
inline
struct
vport
*
ovs_vport_rcu
(
const
struct
datapath
*
dp
,
int
port_no
)
{
WARN_ON_ONCE
(
!
rcu_read_lock_held
());
return
ovs_lookup_vport
(
dp
,
port_no
);
}
static
inline
struct
vport
*
ovs_vport_rtnl_rcu
(
const
struct
datapath
*
dp
,
int
port_no
)
{
WARN_ON_ONCE
(
!
rcu_read_lock_held
()
&&
!
rtnl_is_locked
());
return
ovs_lookup_vport
(
dp
,
port_no
);
}
static
inline
struct
vport
*
ovs_vport_rtnl
(
const
struct
datapath
*
dp
,
int
port_no
)
{
ASSERT_RTNL
();
return
ovs_lookup_vport
(
dp
,
port_no
);
}
/**
/**
* struct ovs_skb_cb - OVS data in skb CB
* struct ovs_skb_cb - OVS data in skb CB
* @flow: The flow associated with this packet. May be %NULL if no flow.
* @flow: The flow associated with this packet. May be %NULL if no flow.
...
@@ -108,6 +132,16 @@ struct dp_upcall_info {
...
@@ -108,6 +132,16 @@ struct dp_upcall_info {
u32
pid
;
u32
pid
;
};
};
static
inline
struct
net
*
ovs_dp_get_net
(
struct
datapath
*
dp
)
{
return
read_pnet
(
&
dp
->
net
);
}
static
inline
void
ovs_dp_set_net
(
struct
datapath
*
dp
,
struct
net
*
net
)
{
write_pnet
(
&
dp
->
net
,
net
);
}
extern
struct
notifier_block
ovs_dp_device_notifier
;
extern
struct
notifier_block
ovs_dp_device_notifier
;
extern
struct
genl_multicast_group
ovs_dp_vport_multicast_group
;
extern
struct
genl_multicast_group
ovs_dp_vport_multicast_group
;
...
...
net/openvswitch/dp_notify.c
View file @
cefd81cf
...
@@ -41,18 +41,20 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
...
@@ -41,18 +41,20 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
case
NETDEV_UNREGISTER
:
case
NETDEV_UNREGISTER
:
if
(
!
ovs_is_internal_dev
(
dev
))
{
if
(
!
ovs_is_internal_dev
(
dev
))
{
struct
sk_buff
*
notify
;
struct
sk_buff
*
notify
;
struct
datapath
*
dp
=
vport
->
dp
;
notify
=
ovs_vport_cmd_build_info
(
vport
,
0
,
0
,
notify
=
ovs_vport_cmd_build_info
(
vport
,
0
,
0
,
OVS_VPORT_CMD_DEL
);
OVS_VPORT_CMD_DEL
);
ovs_dp_detach_port
(
vport
);
ovs_dp_detach_port
(
vport
);
if
(
IS_ERR
(
notify
))
{
if
(
IS_ERR
(
notify
))
{
netlink_set_err
(
init_net
.
genl_sock
,
0
,
netlink_set_err
(
ovs_dp_get_net
(
dp
)
->
genl_sock
,
0
,
ovs_dp_vport_multicast_group
.
id
,
ovs_dp_vport_multicast_group
.
id
,
PTR_ERR
(
notify
));
PTR_ERR
(
notify
));
break
;
break
;
}
}
genlmsg_multicast
(
notify
,
0
,
ovs_dp_vport_multicast_group
.
id
,
genlmsg_multicast_netns
(
ovs_dp_get_net
(
dp
),
notify
,
0
,
ovs_dp_vport_multicast_group
.
id
,
GFP_KERNEL
);
GFP_KERNEL
);
}
}
break
;
break
;
...
...
net/openvswitch/flow.c
View file @
cefd81cf
...
@@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions)
...
@@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions)
int
actions_len
=
nla_len
(
actions
);
int
actions_len
=
nla_len
(
actions
);
struct
sw_flow_actions
*
sfa
;
struct
sw_flow_actions
*
sfa
;
/* At least DP_MAX_PORTS actions are required to be able to flood a
if
(
actions_len
>
MAX_ACTIONS_BUFSIZE
)
* packet to every port. Factor of 2 allows for setting VLAN tags,
* etc. */
if
(
actions_len
>
2
*
DP_MAX_PORTS
*
nla_total_size
(
4
))
return
ERR_PTR
(
-
EINVAL
);
return
ERR_PTR
(
-
EINVAL
);
sfa
=
kmalloc
(
sizeof
(
*
sfa
)
+
actions_len
,
GFP_KERNEL
);
sfa
=
kmalloc
(
sizeof
(
*
sfa
)
+
actions_len
,
GFP_KERNEL
);
...
@@ -992,7 +989,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
...
@@ -992,7 +989,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
swkey
->
phy
.
in_port
=
in_port
;
swkey
->
phy
.
in_port
=
in_port
;
attrs
&=
~
(
1
<<
OVS_KEY_ATTR_IN_PORT
);
attrs
&=
~
(
1
<<
OVS_KEY_ATTR_IN_PORT
);
}
else
{
}
else
{
swkey
->
phy
.
in_port
=
USHRT_MAX
;
swkey
->
phy
.
in_port
=
DP_MAX_PORTS
;
}
}
/* Data attributes. */
/* Data attributes. */
...
@@ -1135,7 +1132,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
...
@@ -1135,7 +1132,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
const
struct
nlattr
*
nla
;
const
struct
nlattr
*
nla
;
int
rem
;
int
rem
;
*
in_port
=
USHRT_MAX
;
*
in_port
=
DP_MAX_PORTS
;
*
priority
=
0
;
*
priority
=
0
;
nla_for_each_nested
(
nla
,
attr
,
rem
)
{
nla_for_each_nested
(
nla
,
attr
,
rem
)
{
...
@@ -1172,7 +1169,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
...
@@ -1172,7 +1169,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
nla_put_u32
(
skb
,
OVS_KEY_ATTR_PRIORITY
,
swkey
->
phy
.
priority
))
nla_put_u32
(
skb
,
OVS_KEY_ATTR_PRIORITY
,
swkey
->
phy
.
priority
))
goto
nla_put_failure
;
goto
nla_put_failure
;
if
(
swkey
->
phy
.
in_port
!=
USHRT_MAX
&&
if
(
swkey
->
phy
.
in_port
!=
DP_MAX_PORTS
&&
nla_put_u32
(
skb
,
OVS_KEY_ATTR_IN_PORT
,
swkey
->
phy
.
in_port
))
nla_put_u32
(
skb
,
OVS_KEY_ATTR_IN_PORT
,
swkey
->
phy
.
in_port
))
goto
nla_put_failure
;
goto
nla_put_failure
;
...
...
net/openvswitch/flow.h
View file @
cefd81cf
...
@@ -43,7 +43,7 @@ struct sw_flow_actions {
...
@@ -43,7 +43,7 @@ struct sw_flow_actions {
struct
sw_flow_key
{
struct
sw_flow_key
{
struct
{
struct
{
u32
priority
;
/* Packet QoS priority. */
u32
priority
;
/* Packet QoS priority. */
u16
in_port
;
/* Input switch port (or
USHRT_MAX
). */
u16
in_port
;
/* Input switch port (or
DP_MAX_PORTS
). */
}
phy
;
}
phy
;
struct
{
struct
{
u8
src
[
ETH_ALEN
];
/* Ethernet source address. */
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,6 +161,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
int
ovs_flow_metadata_from_nlattrs
(
u32
*
priority
,
u16
*
in_port
,
int
ovs_flow_metadata_from_nlattrs
(
u32
*
priority
,
u16
*
in_port
,
const
struct
nlattr
*
);
const
struct
nlattr
*
);
#define MAX_ACTIONS_BUFSIZE (16 * 1024)
#define TBL_MIN_BUCKETS 1024
#define TBL_MIN_BUCKETS 1024
struct
flow_table
{
struct
flow_table
{
...
...
net/openvswitch/vport-internal_dev.c
View file @
cefd81cf
...
@@ -175,9 +175,14 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
...
@@ -175,9 +175,14 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
goto
error_free_vport
;
goto
error_free_vport
;
}
}
dev_net_set
(
netdev_vport
->
dev
,
ovs_dp_get_net
(
vport
->
dp
));
internal_dev
=
internal_dev_priv
(
netdev_vport
->
dev
);
internal_dev
=
internal_dev_priv
(
netdev_vport
->
dev
);
internal_dev
->
vport
=
vport
;
internal_dev
->
vport
=
vport
;
/* Restrict bridge port to current netns. */
if
(
vport
->
port_no
==
OVSP_LOCAL
)
netdev_vport
->
dev
->
features
|=
NETIF_F_NETNS_LOCAL
;
err
=
register_netdevice
(
netdev_vport
->
dev
);
err
=
register_netdevice
(
netdev_vport
->
dev
);
if
(
err
)
if
(
err
)
goto
error_free_netdev
;
goto
error_free_netdev
;
...
...
net/openvswitch/vport-netdev.c
View file @
cefd81cf
...
@@ -83,7 +83,7 @@ static struct vport *netdev_create(const struct vport_parms *parms)
...
@@ -83,7 +83,7 @@ static struct vport *netdev_create(const struct vport_parms *parms)
netdev_vport
=
netdev_vport_priv
(
vport
);
netdev_vport
=
netdev_vport_priv
(
vport
);
netdev_vport
->
dev
=
dev_get_by_name
(
&
init_net
,
parms
->
name
);
netdev_vport
->
dev
=
dev_get_by_name
(
ovs_dp_get_net
(
vport
->
dp
)
,
parms
->
name
);
if
(
!
netdev_vport
->
dev
)
{
if
(
!
netdev_vport
->
dev
)
{
err
=
-
ENODEV
;
err
=
-
ENODEV
;
goto
error_free_vport
;
goto
error_free_vport
;
...
...
net/openvswitch/vport.c
View file @
cefd81cf
...
@@ -16,10 +16,10 @@
...
@@ -16,10 +16,10 @@
* 02110-1301, USA
* 02110-1301, USA
*/
*/
#include <linux/dcache.h>
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
#include <linux/if.h>
#include <linux/if.h>
#include <linux/if_vlan.h>
#include <linux/if_vlan.h>
#include <linux/jhash.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/mutex.h>
...
@@ -27,7 +27,9 @@
...
@@ -27,7 +27,9 @@
#include <linux/rcupdate.h>
#include <linux/rcupdate.h>
#include <linux/rtnetlink.h>
#include <linux/rtnetlink.h>
#include <linux/compat.h>
#include <linux/compat.h>
#include <net/net_namespace.h>
#include "datapath.h"
#include "vport.h"
#include "vport.h"
#include "vport-internal_dev.h"
#include "vport-internal_dev.h"
...
@@ -67,9 +69,9 @@ void ovs_vport_exit(void)
...
@@ -67,9 +69,9 @@ void ovs_vport_exit(void)
kfree
(
dev_table
);
kfree
(
dev_table
);
}
}
static
struct
hlist_head
*
hash_bucket
(
const
char
*
name
)
static
struct
hlist_head
*
hash_bucket
(
struct
net
*
net
,
const
char
*
name
)
{
{
unsigned
int
hash
=
full_name_hash
(
name
,
strlen
(
name
)
);
unsigned
int
hash
=
jhash
(
name
,
strlen
(
name
),
(
unsigned
long
)
net
);
return
&
dev_table
[
hash
&
(
VPORT_HASH_BUCKETS
-
1
)];
return
&
dev_table
[
hash
&
(
VPORT_HASH_BUCKETS
-
1
)];
}
}
...
@@ -80,14 +82,15 @@ static struct hlist_head *hash_bucket(const char *name)
...
@@ -80,14 +82,15 @@ static struct hlist_head *hash_bucket(const char *name)
*
*
* Must be called with RTNL or RCU read lock.
* Must be called with RTNL or RCU read lock.
*/
*/
struct
vport
*
ovs_vport_locate
(
const
char
*
name
)
struct
vport
*
ovs_vport_locate
(
struct
net
*
net
,
const
char
*
name
)
{
{
struct
hlist_head
*
bucket
=
hash_bucket
(
name
);
struct
hlist_head
*
bucket
=
hash_bucket
(
n
et
,
n
ame
);
struct
vport
*
vport
;
struct
vport
*
vport
;
struct
hlist_node
*
node
;
struct
hlist_node
*
node
;
hlist_for_each_entry_rcu
(
vport
,
node
,
bucket
,
hash_node
)
hlist_for_each_entry_rcu
(
vport
,
node
,
bucket
,
hash_node
)
if
(
!
strcmp
(
name
,
vport
->
ops
->
get_name
(
vport
)))
if
(
!
strcmp
(
name
,
vport
->
ops
->
get_name
(
vport
))
&&
net_eq
(
ovs_dp_get_net
(
vport
->
dp
),
net
))
return
vport
;
return
vport
;
return
NULL
;
return
NULL
;
...
@@ -124,6 +127,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
...
@@ -124,6 +127,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
vport
->
port_no
=
parms
->
port_no
;
vport
->
port_no
=
parms
->
port_no
;
vport
->
upcall_pid
=
parms
->
upcall_pid
;
vport
->
upcall_pid
=
parms
->
upcall_pid
;
vport
->
ops
=
ops
;
vport
->
ops
=
ops
;
INIT_HLIST_NODE
(
&
vport
->
dp_hash_node
);
vport
->
percpu_stats
=
alloc_percpu
(
struct
vport_percpu_stats
);
vport
->
percpu_stats
=
alloc_percpu
(
struct
vport_percpu_stats
);
if
(
!
vport
->
percpu_stats
)
{
if
(
!
vport
->
percpu_stats
)
{
...
@@ -170,14 +174,17 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
...
@@ -170,14 +174,17 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
vport_ops_list
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
vport_ops_list
);
i
++
)
{
if
(
vport_ops_list
[
i
]
->
type
==
parms
->
type
)
{
if
(
vport_ops_list
[
i
]
->
type
==
parms
->
type
)
{
struct
hlist_head
*
bucket
;
vport
=
vport_ops_list
[
i
]
->
create
(
parms
);
vport
=
vport_ops_list
[
i
]
->
create
(
parms
);
if
(
IS_ERR
(
vport
))
{
if
(
IS_ERR
(
vport
))
{
err
=
PTR_ERR
(
vport
);
err
=
PTR_ERR
(
vport
);
goto
out
;
goto
out
;
}
}
hlist_add_head_rcu
(
&
vport
->
hash_node
,
bucket
=
hash_bucket
(
ovs_dp_get_net
(
vport
->
dp
),
hash_bucket
(
vport
->
ops
->
get_name
(
vport
)));
vport
->
ops
->
get_name
(
vport
));
hlist_add_head_rcu
(
&
vport
->
hash_node
,
bucket
);
return
vport
;
return
vport
;
}
}
}
}
...
...
net/openvswitch/vport.h
View file @
cefd81cf
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#define VPORT_H 1
#define VPORT_H 1
#include <linux/list.h>
#include <linux/list.h>
#include <linux/netlink.h>
#include <linux/openvswitch.h>
#include <linux/openvswitch.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/spinlock.h>
...
@@ -38,7 +39,7 @@ void ovs_vport_exit(void);
...
@@ -38,7 +39,7 @@ void ovs_vport_exit(void);
struct
vport
*
ovs_vport_add
(
const
struct
vport_parms
*
);
struct
vport
*
ovs_vport_add
(
const
struct
vport_parms
*
);
void
ovs_vport_del
(
struct
vport
*
);
void
ovs_vport_del
(
struct
vport
*
);
struct
vport
*
ovs_vport_locate
(
const
char
*
name
);
struct
vport
*
ovs_vport_locate
(
struct
net
*
net
,
const
char
*
name
);
void
ovs_vport_get_stats
(
struct
vport
*
,
struct
ovs_vport_stats
*
);
void
ovs_vport_get_stats
(
struct
vport
*
,
struct
ovs_vport_stats
*
);
...
@@ -69,10 +70,10 @@ struct vport_err_stats {
...
@@ -69,10 +70,10 @@ struct vport_err_stats {
* @rcu: RCU callback head for deferred destruction.
* @rcu: RCU callback head for deferred destruction.
* @port_no: Index into @dp's @ports array.
* @port_no: Index into @dp's @ports array.
* @dp: Datapath to which this port belongs.
* @dp: Datapath to which this port belongs.
* @node: Element in @dp's @port_list.
* @upcall_pid: The Netlink port to use for packets received on this port that
* @upcall_pid: The Netlink port to use for packets received on this port that
* miss the flow table.
* miss the flow table.
* @hash_node: Element in @dev_table hash table in vport.c.
* @hash_node: Element in @dev_table hash table in vport.c.
* @dp_hash_node: Element in @datapath->ports hash table in datapath.c.
* @ops: Class structure.
* @ops: Class structure.
* @percpu_stats: Points to per-CPU statistics used and maintained by vport
* @percpu_stats: Points to per-CPU statistics used and maintained by vport
* @stats_lock: Protects @err_stats;
* @stats_lock: Protects @err_stats;
...
@@ -82,10 +83,10 @@ struct vport {
...
@@ -82,10 +83,10 @@ struct vport {
struct
rcu_head
rcu
;
struct
rcu_head
rcu
;
u16
port_no
;
u16
port_no
;
struct
datapath
*
dp
;
struct
datapath
*
dp
;
struct
list_head
node
;
u32
upcall_pid
;
u32
upcall_pid
;
struct
hlist_node
hash_node
;
struct
hlist_node
hash_node
;
struct
hlist_node
dp_hash_node
;
const
struct
vport_ops
*
ops
;
const
struct
vport_ops
*
ops
;
struct
vport_percpu_stats
__percpu
*
percpu_stats
;
struct
vport_percpu_stats
__percpu
*
percpu_stats
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment