Rework vlan example to be 1:1, no mac learning
authorBrenden Blanco <bblanco@plumgrid.com>
Fri, 19 Jun 2015 00:53:31 +0000 (17:53 -0700)
committerBrenden Blanco <bblanco@plumgrid.com>
Thu, 18 Jun 2015 13:04:06 +0000 (06:04 -0700)
* 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 <bblanco@plumgrid.com>
examples/hello_world.py
examples/vlan_learning.c
examples/vlan_learning.py

index 9dd73bb..00859b6 100755 (executable)
@@ -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
index 5d2c82b..ae77a8b 100644 (file)
@@ -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);
@@ -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;
@@ -39,8 +40,8 @@ EOP:
 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);
index 079b126..4ae9c8a 100644 (file)
@@ -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
@@ -34,8 +35,7 @@ import sys
 ipr = IPRoute()
 ipdb = IPDB(nl=ipr)
 
-num_workers = 3
-num_clients = 9
+num_clients = 3
 num_vlans = 16
 
 # load the bpf program
@@ -52,7 +52,7 @@ class VlanSimulation(Simulation):
 
     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"]
@@ -84,32 +84,27 @@ class VlanSimulation(Simulation):
         # 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)