Skip to content

Commit

Permalink
Rework vlan example to be 1:1, no mac learning
Browse files Browse the repository at this point in the history
* Use ifindex instead of src_mac to program egress table
* Remove the static arp programming
* Get the example to work in python2

Signed-off-by: Brenden Blanco <[email protected]>
  • Loading branch information
Brenden Blanco committed Jun 18, 2015
1 parent 439e53c commit 6bf723d
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 20 deletions.
4 changes: 2 additions & 2 deletions examples/hello_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

# run in project directory with:
# sudo bash -c "PYTHONPATH=$PWD/src LD_LIBRARY_PATH=$PWD/build/src/cc examples/hello_world.py"
# run in project examples directory with:
# sudo ./hello_world.py"

from bpf import BPF
from subprocess import call
Expand Down
9 changes: 5 additions & 4 deletions examples/vlan_learning.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct ifindex_leaf_t {
};

// redirect based on mac -> out_ifindex (auto-learning)
BPF_TABLE("hash", u64, struct ifindex_leaf_t, egress, 4096);
BPF_TABLE("hash", int, struct ifindex_leaf_t, egress, 4096);

// redirect based on mac -> out_ifindex (config-driven)
BPF_TABLE("hash", u64, struct ifindex_leaf_t, ingress, 4096);
Expand All @@ -24,8 +24,9 @@ int handle_phys2virt(struct __sk_buff *skb) {
lock_xadd(&leaf->tx_pkts, 1);
lock_xadd(&leaf->tx_bytes, skb->len);
// auto-program reverse direction table
int out_ifindex = leaf->out_ifindex;
struct ifindex_leaf_t zleaf = {0};
struct ifindex_leaf_t *out_leaf = egress.lookup_or_init(&src_mac, &zleaf);
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;
Expand All @@ -39,8 +40,8 @@ int handle_phys2virt(struct __sk_buff *skb) {
int handle_virt2phys(struct __sk_buff *skb) {
BEGIN(ethernet);
PROTO(ethernet) {
u64 dst_mac = ethernet->dst;
struct ifindex_leaf_t *leaf = egress.lookup(&dst_mac);
int src_ifindex = skb->ifindex;
struct ifindex_leaf_t *leaf = egress.lookup(&src_ifindex);
if (leaf) {
lock_xadd(&leaf->tx_pkts, 1);
lock_xadd(&leaf->tx_bytes, skb->len);
Expand Down
23 changes: 9 additions & 14 deletions examples/vlan_learning.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# switch | subinterface |

from bpf import BPF
from builtins import input
from ctypes import c_uint, c_int, c_ulonglong, Structure
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
from random import shuffle
Expand All @@ -34,8 +35,7 @@
ipr = IPRoute()
ipdb = IPDB(nl=ipr)

num_workers = 3
num_clients = 9
num_clients = 3
num_vlans = 16

# load the bpf program
Expand All @@ -52,7 +52,7 @@ def __init__(self, ipdb):

def start(self):
# start identical workers each in a namespace
for i in range(0, num_workers):
for i in range(0, num_clients):
httpmod = ("SimpleHTTPServer" if sys.version_info[0] < 3
else "http.server")
cmd = ["python", "-m", httpmod, "80"]
Expand Down Expand Up @@ -84,32 +84,27 @@ def start(self):
# allocate vlans randomly
available_vlans = [i for i in range(2, 2 + num_vlans)]
shuffle(available_vlans)
available_ips = [[i for i in range(100, 105)] for i in range(0, num_workers)]
available_ips = [[i for i in range(100, 105)] for i in range(0, num_clients)]

# these are simulations of physical clients
for i in range(0, num_clients):
worker_i = i % num_workers
ipaddr = "172.16.1.%d" % available_ips[worker_i].pop(0)
macaddr = ("02:00:00:%.2x:%.2x:%.2x" %
((i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff))

# program arp manually
p = NSPopen("worker%d" % worker_i, ["arp", "-s", ipaddr, macaddr])
p.communicate(); p.wait(); p.release()

# assign this client to the given worker
idx = self.ipdb.interfaces["worker%da" % worker_i]["index"]
idx = self.ipdb.interfaces["worker%da" % i]["index"]
mac = int(macaddr.replace(":", ""), 16)
ingress[ingress.Key(mac)] = ingress.Leaf(idx, 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,
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,
ipaddr=ipaddr + "/24", macaddr=macaddr,
cmd=cmd)[1:3]
ipaddr="172.16.1.100/24",
macaddr=macaddr, cmd=cmd)[1:3]

try:
sim = VlanSimulation(ipdb)
Expand Down

0 comments on commit 6bf723d

Please sign in to comment.