Commit ffaee08c authored by Brenden Blanco's avatar Brenden Blanco

Merge pull request #83 from iovisor/yhs_dev

Yhs dev
parents 0fa99f4d 00eb0883
import atexit import subprocess
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
class Simulation(object): class Simulation(object):
...@@ -14,15 +14,22 @@ class Simulation(object): ...@@ -14,15 +14,22 @@ class Simulation(object):
self.processes = [] self.processes = []
self.released = False self.released = False
# helper function to create a namespace and a veth connecting it # helper function to add additional ifc to namespace
def _create_ns(self, name, in_ifc=None, out_ifc=None, ipaddr=None, # if called directly outside Simulation class, "ifc_base_name" should be
macaddr=None, fn=None, cmd=None, action="ok"): # different from "name", the "ifc_base_name" and "name" are the same for
ns_ipdb = IPDB(nl=NetNS(name)) # the first ifc created by namespace
def _ns_add_ifc(self, name, ns_ifc, ifc_base_name, in_ifc=None, out_ifc=None,
ipaddr=None, macaddr=None, fn=None, cmd=None, action="ok",
disable_ipv6=False):
if name in self.ipdbs:
ns_ipdb = self.ipdbs[name]
else:
ns_ipdb = IPDB(nl=NetNS(name))
if in_ifc: if in_ifc:
in_ifname = in_ifc.ifname in_ifname = in_ifc.ifname
else: else:
out_ifc = self.ipdb.create(ifname="%sa" % name, kind="veth", out_ifc = self.ipdb.create(ifname="%sa" % ifc_base_name, kind="veth",
peer="%sb" % name).commit() peer="%sb" % ifc_base_name).commit()
in_ifc = self.ipdb.interfaces[out_ifc.peer] in_ifc = self.ipdb.interfaces[out_ifc.peer]
in_ifname = in_ifc.ifname in_ifname = in_ifc.ifname
with in_ifc as v: with in_ifc as v:
...@@ -31,21 +38,36 @@ class Simulation(object): ...@@ -31,21 +38,36 @@ class Simulation(object):
in_ifc = ns_ipdb.interfaces[in_ifname] in_ifc = ns_ipdb.interfaces[in_ifname]
if out_ifc: out_ifc.up().commit() if out_ifc: out_ifc.up().commit()
with in_ifc as v: with in_ifc as v:
v.ifname = "eth0" v.ifname = ns_ifc
if ipaddr: v.add_ip("%s" % ipaddr) if ipaddr: v.add_ip("%s" % ipaddr)
if macaddr: v.address = macaddr if macaddr: v.address = macaddr
v.up() v.up()
# if required, disable ipv6 before attaching the filter
if disable_ipv6:
subprocess.call(["sysctl", "-q", "-w",
"net.ipv6.conf." + out_ifc.ifname+ ".disable_ipv6=1"])
nsp = NSPopen(ns_ipdb.nl.netns,
["sysctl", "-q", "-w", "net.ipv6.conf." + ns_ifc + ".disable_ipv6=1"])
nsp.wait(); nsp.release()
if fn and out_ifc: if fn and out_ifc:
self.ipdb.nl.tc("add", "ingress", out_ifc["index"], "ffff:") self.ipdb.nl.tc("add", "ingress", out_ifc["index"], "ffff:")
self.ipdb.nl.tc("add-filter", "bpf", out_ifc["index"], ":1", self.ipdb.nl.tc("add-filter", "bpf", out_ifc["index"], ":1",
fd=fn.fd, name=fn.name, parent="ffff:", fd=fn.fd, name=fn.name, parent="ffff:",
action=action, classid=1) action=action, classid=1)
self.ipdbs[ns_ipdb.nl.netns] = ns_ipdb
self.namespaces.append(ns_ipdb.nl)
if cmd: if cmd:
self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd)) self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd))
return (ns_ipdb, out_ifc, in_ifc) return (ns_ipdb, out_ifc, in_ifc)
# helper function to create a namespace and a veth connecting it
def _create_ns(self, name, in_ifc=None, out_ifc=None, ipaddr=None,
macaddr=None, fn=None, cmd=None, action="ok", disable_ipv6=False):
(ns_ipdb, out_ifc, in_ifc) = self._ns_add_ifc(name, "eth0", name, in_ifc, out_ifc,
ipaddr, macaddr, fn, cmd, action,
disable_ipv6)
self.ipdbs[ns_ipdb.nl.netns] = ns_ipdb
self.namespaces.append(ns_ipdb.nl)
return (ns_ipdb, out_ifc, in_ifc)
def release(self): def release(self):
if self.released: return if self.released: return
self.released = True self.released = True
......
../../examples/simulation.py
\ No newline at end of file
...@@ -101,13 +101,12 @@ int pem(struct __sk_buff *skb) { ...@@ -101,13 +101,12 @@ int pem(struct __sk_buff *skb) {
} }
} }
return 0; return 1;
} }
static int br_common(struct __sk_buff *skb, int which_br) __attribute__((always_inline)); static int br_common(struct __sk_buff *skb, int which_br) __attribute__((always_inline));
static int br_common(struct __sk_buff *skb, int which_br) { static int br_common(struct __sk_buff *skb, int which_br) {
u8 *cursor = 0; u8 *cursor = 0;
bpf_metadata_t meta = {};
u16 proto; u16 proto;
u16 arpop; u16 arpop;
eth_addr_t dmac; eth_addr_t dmac;
...@@ -118,20 +117,16 @@ static int br_common(struct __sk_buff *skb, int which_br) { ...@@ -118,20 +117,16 @@ static int br_common(struct __sk_buff *skb, int which_br) {
bpf_dest_t *dest_p; bpf_dest_t *dest_p;
u32 index, *rtrif_p; u32 index, *rtrif_p;
if (skb->tc_index == 0) {
skb->tc_index = 1;
skb->cb[0] = skb->cb[1] = 0;
meta.prog_id = meta.rx_port_id = 0;
} else {
meta.prog_id = skb->cb[0];
meta.rx_port_id = skb->cb[1];
}
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet)); struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
/* handle ethernet packet header */
{ {
dmac.addr = ethernet->dst; dmac.addr = ethernet->dst;
if (meta.prog_id != 0) { /* skb->tc_index may be preserved accross router namespace if router simply rewrite packet
/* send to the router */ * and send it back.
*/
if (skb->tc_index == 1) {
/* packet from pem, send to the router, set tc_index to 2 */
skb->tc_index = 2;
if (dmac.addr == 0xffffffffffffULL) { if (dmac.addr == 0xffffffffffffULL) {
index = 0; index = 0;
if (which_br == 1) if (which_br == 1)
...@@ -149,9 +144,11 @@ static int br_common(struct __sk_buff *skb, int which_br) { ...@@ -149,9 +144,11 @@ static int br_common(struct __sk_buff *skb, int which_br) {
if (rtrif_p) if (rtrif_p)
bpf_clone_redirect(skb, *rtrif_p, 0); bpf_clone_redirect(skb, *rtrif_p, 0);
} }
return 0; return 1;
} }
/* set the tc_index to 1 so pem knows it is from internal */
skb->tc_index = 1;
switch (ethernet->type) { switch (ethernet->type) {
case ETH_P_IP: goto ip; case ETH_P_IP: goto ip;
case ETH_P_ARP: goto arp; case ETH_P_ARP: goto arp;
...@@ -217,7 +214,7 @@ xmit: ...@@ -217,7 +214,7 @@ xmit:
} }
EOP: EOP:
return 0; return 1;
} }
int br1(struct __sk_buff *skb) { int br1(struct __sk_buff *skb) {
......
This diff is collapsed.
...@@ -24,5 +24,5 @@ int pem(struct __sk_buff *skb) { ...@@ -24,5 +24,5 @@ int pem(struct __sk_buff *skb) {
bpf_clone_redirect(skb, *ifindex_p, 0); bpf_clone_redirect(skb, *ifindex_p, 0);
} }
return 0; return 1;
} }
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment