Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
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
Kirill Smelkov
bcc
Commits
540d45a0
Commit
540d45a0
authored
Jul 22, 2015
by
Yonghong Song
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
simply vlan_learning example with newer vlan_push/pop helpers
Signed-off-by:
Yonghong Song
<
yhs@plumgrid.com
>
parent
c366fcf2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
47 additions
and
30 deletions
+47
-30
examples/vlan_learning.c
examples/vlan_learning.c
+13
-0
examples/vlan_learning.py
examples/vlan_learning.py
+19
-30
src/cc/compat/linux/bpf.h
src/cc/compat/linux/bpf.h
+9
-0
src/cc/export/helpers.h
src/cc/export/helpers.h
+6
-0
No files found.
examples/vlan_learning.c
View file @
540d45a0
...
...
@@ -5,6 +5,8 @@
struct
ifindex_leaf_t
{
int
out_ifindex
;
int
vlan_tci
;
// populated by phys2virt and used by virt2phys
int
vlan_proto
;
// populated by phys2virt and used by virt2phys
u64
tx_pkts
;
u64
tx_bytes
;
};
...
...
@@ -16,6 +18,9 @@ BPF_TABLE("hash", int, struct ifindex_leaf_t, egress, 4096);
BPF_TABLE
(
"hash"
,
u64
,
struct
ifindex_leaf_t
,
ingress
,
4096
);
int
handle_phys2virt
(
struct
__sk_buff
*
skb
)
{
// only handle vlan packets
if
(
!
skb
->
vlan_present
)
return
1
;
u8
*
cursor
=
0
;
ethernet:
{
struct
ethernet_t
*
ethernet
=
cursor_advance
(
cursor
,
sizeof
(
*
ethernet
));
...
...
@@ -31,6 +36,13 @@ int handle_phys2virt(struct __sk_buff *skb) {
// relearn when mac moves ifindex
if
(
out_leaf
->
out_ifindex
!=
skb
->
ifindex
)
out_leaf
->
out_ifindex
=
skb
->
ifindex
;
// relearn when vlan_tci/vlan_proto changes
if
(
out_leaf
->
vlan_tci
!=
skb
->
vlan_tci
)
out_leaf
->
vlan_tci
=
skb
->
vlan_tci
;
if
(
out_leaf
->
vlan_proto
!=
skb
->
vlan_proto
)
out_leaf
->
vlan_proto
=
skb
->
vlan_proto
;
// pop the vlan header and send to the destination
bpf_skb_vlan_pop
(
skb
);
bpf_clone_redirect
(
skb
,
leaf
->
out_ifindex
,
0
);
}
}
...
...
@@ -46,6 +58,7 @@ int handle_virt2phys(struct __sk_buff *skb) {
if
(
leaf
)
{
lock_xadd
(
&
leaf
->
tx_pkts
,
1
);
lock_xadd
(
&
leaf
->
tx_bytes
,
skb
->
len
);
bpf_skb_vlan_push
(
skb
,
leaf
->
vlan_proto
,
leaf
->
vlan_tci
);
bpf_clone_redirect
(
skb
,
leaf
->
out_ifindex
,
0
);
}
}
...
...
examples/vlan_learning.py
View file @
540d45a0
...
...
@@ -14,14 +14,14 @@
# overlapping IP spaces and the traffic will still work.
# | bpf program |
# cli0 --| |
|----\
/--|-- worker0 |
# cli1 --| trunk |
|--
--->-handle_p2v(pkt)-> /---|-- worker1 |
# cli2 --|=======|=
|----/
/----|-- worker2 |
# ... --| |
|---/
<-handle_v2p(pkt)-<-----|-- ... |
# cliN --| |
|--/
\----|-- workerM |
# | |
^
^ |
# phys |
vlan
veth |
# switch |
subinterface
|
# cli0 --| |
/--|-- worker0 |
# cli1 --| trunk |
+->
--->-handle_p2v(pkt)-> /---|-- worker1 |
# cli2 --|=======|=
+
/----|-- worker2 |
# ... --| |
+-<---
<-handle_v2p(pkt)-<-----|-- ... |
# cliN --| |
\----|-- workerM |
# | |
^ |
# phys |
veth |
# switch |
|
from
bpf
import
BPF
from
builtins
import
input
...
...
@@ -63,22 +63,12 @@ class VlanSimulation(Simulation):
v
.
up
()
self
.
ipdb
.
interfaces
.
eth0b
.
up
().
commit
()
# connect the trunk to the bridge
with
self
.
ipdb
.
create
(
ifname
=
"br100"
,
kind
=
"bridge"
)
as
br100
:
br100
.
add_port
(
self
.
ipdb
.
interfaces
.
eth0b
)
br100
.
up
()
# for each vlan, create a subinterface on the eth...most of these will be
# unused, but still listening and waiting for a client to send traffic on
for
i
in
range
(
2
,
2
+
num_vlans
):
with
self
.
ipdb
.
create
(
ifname
=
"eth0a.%d"
%
i
,
kind
=
"vlan"
,
link
=
ipdb
.
interfaces
.
eth0a
,
vlan_id
=
i
)
as
v
:
v
.
up
()
v
=
self
.
ipdb
.
interfaces
[
"eth0a.%d"
%
i
]
# add the bpf program for demuxing phys2virt packets
ipr
.
tc
(
"add"
,
"ingress"
,
v
[
"index"
],
"ffff:"
)
ipr
.
tc
(
"add-filter"
,
"bpf"
,
v
[
"index"
],
":1"
,
fd
=
phys_fn
.
fd
,
name
=
phys_fn
.
name
,
parent
=
"ffff:"
,
action
=
"drop"
,
classid
=
1
)
# eth0a will be hooked to clients with vlan interfaces
# add the bpf program to eth0b for demuxing phys2virt packets
v
=
self
.
ipdb
.
interfaces
[
"eth0b"
]
ipr
.
tc
(
"add"
,
"ingress"
,
v
[
"index"
],
"ffff:"
)
ipr
.
tc
(
"add-filter"
,
"bpf"
,
v
[
"index"
],
":1"
,
fd
=
phys_fn
.
fd
,
name
=
phys_fn
.
name
,
parent
=
"ffff:"
,
action
=
"drop"
,
classid
=
1
)
# allocate vlans randomly
available_vlans
=
[
i
for
i
in
range
(
2
,
2
+
num_vlans
)]
...
...
@@ -93,15 +83,15 @@ class VlanSimulation(Simulation):
# assign this client to the given worker
idx
=
self
.
ipdb
.
interfaces
[
"worker%da"
%
i
][
"index"
]
mac
=
int
(
macaddr
.
replace
(
":"
,
""
),
16
)
ingress
[
ingress
.
Key
(
mac
)]
=
ingress
.
Leaf
(
idx
,
0
,
0
)
ingress
[
ingress
.
Key
(
mac
)]
=
ingress
.
Leaf
(
idx
,
0
,
0
,
0
,
0
)
# test traffic with curl loop
cmd
=
[
"bash"
,
"-c"
,
"for i in {1..8}; do curl 172.16.1.5 -o /dev/null; sleep 1; done"
]
br_ifc
=
self
.
ipdb
.
create
(
ifname
=
"br100
.%d"
%
i
,
kind
=
"vlan"
,
link
=
br100
,
vlan_id
=
available_vlans
.
pop
(
0
)).
commit
()
(
out_ifc
,
in_ifc
)
=
self
.
_create_ns
(
"client%d"
%
i
,
in_ifc
=
br
_ifc
,
client_ifc
=
self
.
ipdb
.
create
(
ifname
=
"eth0a
.%d"
%
i
,
kind
=
"vlan"
,
link
=
self
.
ipdb
.
interfaces
[
"eth0a"
]
,
vlan_id
=
available_vlans
.
pop
(
0
)).
commit
()
(
out_ifc
,
in_ifc
)
=
self
.
_create_ns
(
"client%d"
%
i
,
in_ifc
=
client
_ifc
,
ipaddr
=
"172.16.1.100/24"
,
macaddr
=
macaddr
,
cmd
=
cmd
)[
1
:
3
]
...
...
@@ -123,6 +113,5 @@ try:
print
(
" tx pkts = %u, tx bytes = %u"
%
(
v
[
2
],
v
[
3
]))
finally
:
if
"eth0a"
in
ipdb
.
interfaces
:
ipdb
.
interfaces
.
eth0a
.
remove
().
commit
()
if
"br100"
in
ipdb
.
interfaces
:
ipdb
.
interfaces
.
br100
.
remove
().
commit
()
if
"sim"
in
locals
():
sim
.
release
()
ipdb
.
release
()
src/cc/compat/linux/bpf.h
View file @
540d45a0
...
...
@@ -249,6 +249,15 @@ enum bpf_func_id {
* Return: 0 on success
*/
BPF_FUNC_get_current_comm
,
/**
* bpf_get_cgroup_classid(skb) - retrieve a proc's classid
* @skb: pointer to skb
* Return: classid if != 0
*/
BPF_FUNC_get_cgroup_classid
,
BPF_FUNC_skb_vlan_push
,
/* bpf_skb_vlan_push(skb, vlan_proto, vlan_tci) */
BPF_FUNC_skb_vlan_pop
,
/* bpf_skb_vlan_pop(skb) */
__BPF_FUNC_MAX_ID
,
};
...
...
src/cc/export/helpers.h
View file @
540d45a0
...
...
@@ -74,6 +74,12 @@ static u64 (*bpf_get_current_uid_gid)(void) =
(
void
*
)
BPF_FUNC_get_current_uid_gid
;
static
int
(
*
bpf_get_current_comm
)(
void
*
buf
,
int
buf_size
)
=
(
void
*
)
BPF_FUNC_get_current_comm
;
static
u64
(
*
bpf_get_cgroup_classid
)(
void
*
ctx
)
=
(
void
*
)
BPF_FUNC_get_cgroup_classid
;
static
u64
(
*
bpf_skb_vlan_push
)(
void
*
ctx
,
u16
proto
,
u16
vlan_tci
)
=
(
void
*
)
BPF_FUNC_skb_vlan_push
;
static
u64
(
*
bpf_skb_vlan_pop
)(
void
*
ctx
)
=
(
void
*
)
BPF_FUNC_skb_vlan_pop
;
static
void
bpf_tail_call_
(
u64
map_fd
,
void
*
ctx
,
int
index
)
{
((
void
(
*
)(
void
*
,
u64
,
int
))
BPF_FUNC_tail_call
)(
ctx
,
map_fd
,
index
);
}
...
...
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