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
8a9747c9
Commit
8a9747c9
authored
Jul 22, 2015
by
Brenden Blanco
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #90 from iovisor/yhs_dev
simply vlan_learning example with newer vlan_push/pop helpers
parents
c366fcf2
6d8381c7
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
46 additions
and
33 deletions
+46
-33
examples/vlan_learning.c
examples/vlan_learning.c
+12
-3
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 @
8a9747c9
...
...
@@ -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
));
...
...
@@ -28,9 +33,12 @@ int handle_phys2virt(struct __sk_buff *skb) {
int
out_ifindex
=
leaf
->
out_ifindex
;
struct
ifindex_leaf_t
zleaf
=
{
0
};
struct
ifindex_leaf_t
*
out_leaf
=
egress
.
lookup_or_init
(
&
out_ifindex
,
&
zleaf
);
// relearn when mac moves ifindex
if
(
out_leaf
->
out_ifindex
!=
skb
->
ifindex
)
out_leaf
->
out_ifindex
=
skb
->
ifindex
;
// to capture potential configuration changes
out_leaf
->
out_ifindex
=
skb
->
ifindex
;
out_leaf
->
vlan_tci
=
skb
->
vlan_tci
;
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 +54,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 @
8a9747c9
...
...
@@ -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 @
8a9747c9
...
...
@@ -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 @
8a9747c9
...
...
@@ -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