Malá učebnice OpenFlow (13) – tabulky v praxi OpenvSwitch

Část 13 z celkových 15 v seriálu Malá učebnice OpenFlow

Jak už je v tomto seriálu zvykem, ukážeme si dnes něco nového v praxi a k teorii se vrátíme později. Jak se dá použít vícero OpenFlow tabulek?

OpenFlow verze 1.0 pracoval jen s jednou tabulkou pravidel a to se ukázalo jako velmi neefektivní a navíc extrémně nepříznivé pro reálné hardwarové implementace. Pozdější verze protokolu, včetně dnes preferované 1.3, podporují vícero zřetězených tabulek. Proč je to tak důležité a jak to protokol dělá si řekneme příště, protože dnes začneme praxí. Vyzkoušíme si rozdíl mezi jednou tabulkou a vícero tabulkami v praxi.

Hardwarové prostředky jsou předem dané a omezené (o tom také později), takže se dnes zaměříme na softwarovou implementaci v OpenvSwitch, který je součástí našeho Miininet prostředí. Vytvoříme si určitý scénář pravidel a tato naplníme nejprve do více tabulek a pak pouze do jedné. Nebudeme používat kontroler, ale budeme zadávat záznamy do OVS (OpenvSwitch) z příkazové řádky. Ani nepoužijeme skutečný provoz – OVS má v příkazové řádce i simulátor, který nám řekne, jak by skutečné vyhodnocení provozu probíhalo.

Více tabulek a OVS

OpenvSwitch je softwarová implementace OpenFlow a nabízí vysokou flexibilitu, která není omezená možnostmi rychlého, leč málo přizpůsobivého hardwaru. Při vyhodnocování pravidel můžeme zadat i akci GOTO_TABLE, tedy ukonči zpracování v aktuální tabulce a skoč do jiné (detaily si vysvětlíme příště). Pojďme teď implementovat následující požadavek. Chceme rozdělit uživatele do skupin podle zdrojové IP a jakékoli jiné adresy dropovat. V každé skupině chceme používat jiné politiky pro arkování provozu DSCP kódem (QoS) marking pro odlišné cílové stanice. Pakliže není řečeno jinak, tak provoz z těchto zdrojových IP budeme posílat normálně. Vyřešme to hierarchií tabulek.

Spusťte si Mininet s jediným prvkem a otevřete si druhou session do Mininet VM (tedy abyste mohli zadávat příkazy mimo Mininet CLI).

sudo mn --switch ovs,protocols=OpenFlow13

mininet@mininet-vm:~$ sudo -i
root@mininet-vm:~# sudo ovs-vsctl show
aad071f2-ee72-47c0-a963-8cb5c033ad1b
Bridge "s1"
Controller "ptcp:6634"
Controller "tcp:127.0.0.1:6633"
fail_mode: secure
Port "s1"
Interface "s1"
type: internal
Port "s1-eth1"
Interface "s1-eth1"
Port "s1-eth2"
Interface "s1-eth2"
ovs_version: "2.0.2"

Jak vidíte Mininet vytvořit jeden OpenvSwitch s názvem s1 a s tím teď budeme pracovat. Přes podobný příkaz můžeme zadávat přímo flow pravidla.

První tabulka má číslo 0 a budeme v ní řešit zdrojové IP a jejich rozřazení do skupin. Pro každou specifickou skupinu bude akcí poskočení na jí specifickou tabulku.:

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.1 actions=goto_table(1) -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.2 actions=goto_table(1) -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.3 actions=goto_table(1) -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.4 actions=goto_table(2) -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.5 actions=goto_table(2) -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.6 actions=goto_table(2) -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 actions=drop -O OpenFlow13

Máme tedy 3 zdrojové IP v jedné skupině (skáče do tabulky 1) a 3 zdrojové IP v druhé skupině (skáče do tabulky 2) + všechno ostatní na IP úrovni zahazujeme. Takhle bychom pak mohli implementovat ona per-destination-ip QoS marking pravidla pro první a druhou skupinu:

ovs-ofctl add-flow s1 "table=1 dl_type=0x0800 nw_dst=10.1.0.1 actions=mod_nw_tos:64,normal -O OpenFlow13
ovs-ofctl add-flow s1 "table=1 dl_type=0x0800 nw_dst=10.1.0.2 actions=mod_nw_tos:48,normal -O OpenFlow13
ovs-ofctl add-flow s1 "table=1 dl_type=0x0800 nw_dst=10.1.0.3 actions=mod_nw_tos:32,normal -O OpenFlow13
ovs-ofctl add-flow s1 "table=1 actions=normal -O OpenFlow13

ovs-ofctl add-flow s1 "table=2 dl_type=0x0800 nw_dst=10.2.0.1 actions=mod_nw_tos:64,normal -O OpenFlow13
ovs-ofctl add-flow s1 "table=2 dl_type=0x0800 nw_dst=10.2.0.2 actions=mod_nw_tos:48,normal -O OpenFlow13
ovs-ofctl add-flow s1 "table=2 dl_type=0x0800 nw_dst=10.2.0.3 actions=mod_nw_tos:32,normal -O OpenFlow13
ovs-ofctl add-flow s1 "table=2 actions=normal" -O OpenFlow13

Tedy pro některé destination IP budeme markovat DSCP kódem, pro jiné pošleme normálně. Takhle si můžete vypsat aktuální pravidla z OVS a ověřit, že to sedí:

root@mininet-vm:~# ovs-ofctl dump-flows s1 -O OpenFlow13
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x0, duration=9.883s, table=0, n_packets=0, n_bytes=0, ip,nw_src=10.0.0.2 actions=goto_table:1
cookie=0x0, duration=9.851s, table=0, n_packets=0, n_bytes=0, ip,nw_src=10.0.0.6 actions=goto_table:2
cookie=0x0, duration=9.867s, table=0, n_packets=0, n_bytes=0, ip,nw_src=10.0.0.4 actions=goto_table:2
cookie=0x0, duration=9.858s, table=0, n_packets=0, n_bytes=0, ip,nw_src=10.0.0.5 actions=goto_table:2
cookie=0x0, duration=9.875s, table=0, n_packets=0, n_bytes=0, ip,nw_src=10.0.0.3 actions=goto_table:1
cookie=0x0, duration=9.891s, table=0, n_packets=0, n_bytes=0, ip,nw_src=10.0.0.1 actions=goto_table:1
cookie=0x0, duration=9.844s, table=0, n_packets=0, n_bytes=0, ip actions=drop
cookie=0x0, duration=9.816s, table=1, n_packets=0, n_bytes=0, ip,nw_dst=10.1.0.3 actions=mod_nw_tos:32,NORMAL
cookie=0x0, duration=9.835s, table=1, n_packets=0, n_bytes=0, ip,nw_dst=10.1.0.1 actions=mod_nw_tos:64,NORMAL
cookie=0x0, duration=9.824s, table=1, n_packets=0, n_bytes=0, ip,nw_dst=10.1.0.2 actions=mod_nw_tos:48,NORMAL
cookie=0x0, duration=9.808s, table=1, n_packets=0, n_bytes=0, actions=NORMAL
cookie=0x0, duration=9.782s, table=2, n_packets=0, n_bytes=0, ip,nw_dst=10.2.0.3 actions=mod_nw_tos:32,NORMAL
cookie=0x0, duration=9.799s, table=2, n_packets=0, n_bytes=0, ip,nw_dst=10.2.0.1 actions=mod_nw_tos:64,NORMAL
cookie=0x0, duration=9.79s, table=2, n_packets=0, n_bytes=0, ip,nw_dst=10.2.0.2 actions=mod_nw_tos:48,NORMAL
cookie=0x0, duration=8.143s, table=2, n_packets=0, n_bytes=0, actions=NORMAL
root@mininet-vm:~#

OVS disponuje krásným testovacím příkazem ovs-appctl ofproto/trace, po kterém zadáte prvek a parametry zkoušeného paketu. Výstupem je znázornění rozhodovacího procesu a hlavně výsledná akce. Pojďme si vyzkoušet, že naše pravidla fungují tak, jak jsme chtěli:

root@mininet-vm:~# ovs-appctl ofproto/trace s1 dl_type=0x0800,nw_src=10.0.0.1,nw_dst=1.1.1.1
Flow: ip,metadata=0,in_port=ANY,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.1,nw_dst=1.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=0
Rule: table=0 cookie=0 ip,nw_src=10.0.0.1
OpenFlow actions=goto_table:1

Resubmitted flow: unchanged
Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
Resubmitted odp: drop
Rule: table=1 cookie=0
OpenFlow actions=NORMAL
no learned MAC for destination, flooding

Final flow: unchanged
Relevant fields: skb_priority=0,ip,in_port=ANY,vlan_tci=0x0000/0x1fff,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.1,nw_dst=1.1.1.1,nw_frag=no
Datapath actions: 2,1,3
root@mininet-vm:~#

Tedy z 10.0.0.1 na 1.1.1.1 je to NORMAL

root@mininet-vm:~# ovs-appctl ofproto/trace s1 dl_type=0x0800,nw_src=1.1.1.1,nw_dst=10.1.0.1
Flow: ip,metadata=0,in_port=ANY,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=1.1.1.1,nw_dst=10.1.0.1,nw_tos=0,nw_ecn=0,nw_ttl=0
Rule: table=0 cookie=0 ip
OpenFlow actions=drop

Final flow: unchanged
Relevant fields: skb_priority=0,ip,in_port=ANY,nw_src=1.1.1.1,nw_frag=no
Datapath actions: drop
root@mininet-vm:~#

Z 1.1.1.1 na 10.1.0.1 je to DROP

root@mininet-vm:~# ovs-appctl ofproto/trace s1 dl_type=0x0800,nw_src=10.0.0.3,nw_dst=10.1.0.1
Flow: ip,metadata=0,in_port=ANY,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.3,nw_dst=10.1.0.1,nw_tos=0,nw_ecn=0,nw_ttl=0
Rule: table=0 cookie=0 ip,nw_src=10.0.0.3
OpenFlow actions=goto_table:1

Resubmitted flow: unchanged
Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
Resubmitted odp: drop
Rule: table=1 cookie=0 ip,nw_dst=10.1.0.1
OpenFlow actions=mod_nw_tos:64,NORMAL
no learned MAC for destination, flooding

Final flow: ip,metadata=0,in_port=ANY,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.3,nw_dst=10.1.0.1,nw_tos=64,nw_ecn=0,nw_ttl=0
Relevant fields: skb_priority=0,ip,in_port=ANY,vlan_tci=0x0000/0x1fff,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,nw_src=10.0.0.3,nw_dst=10.1.0.1,nw_tos=0,nw_frag=no
Datapath actions: 2,1,3
root@mininet-vm:~#

Z 10.0.0.3 na 10.1.0.1 remarkujeme na 64 + posíláme normálně. Další výpisy už jen zkrácené:

root@mininet-vm:~# ovs-appctl ofproto/trace s1 dl_type=0x0800,nw_src=10.0.0.4,nw_dst=10.1.0.1
Rule: table=0 cookie=0 ip,nw_src=10.0.0.4
OpenFlow actions=goto_table:2

Rule: table=2 cookie=0
OpenFlow actions=NORMAL

root@mininet-vm:~# ovs-appctl ofproto/trace s1 dl_type=0x0800,nw_src=10.0.0.4,nw_dst=10.2.0.1
Rule: table=0 cookie=0 ip,nw_src=10.0.0.4
OpenFlow actions=goto_table:2

Rule: table=2 cookie=0 ip,nw_dst=10.2.0.1
OpenFlow actions=mod_nw_tos:64,NORMAL

Právě jste úspěšně vyzkoušeli použití více tabulek v rámci OpenFlow pipeline. Příště si řekneme detailně jaké jsou možnosti a hlavně zda jsou nějaká omezení v hardware implementacích. Dnes ale ještě (napovídám na příště jednu z výhod) zkusme dosáhnout téhož v jediné tabulce. Půjde to?

Totéž v jedné tabulce

Samozřejmě že půjde – takhle:

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.1 nw_dst=10.1.0.1 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.1 nw_dst=10.1.0.2 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.1 nw_dst=10.1.0.3 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "priority=10000 dl_type=0x0800 nw_src=10.0.0.1 actions=normal" -O OpenFlow13

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.2 nw_dst=10.1.0.1 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.2 nw_dst=10.1.0.2 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.2 nw_dst=10.1.0.3 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "priority=10000 dl_type=0x0800 nw_src=10.0.0.2 actions=normal" -O OpenFlow13

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.3 nw_dst=10.1.0.1 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.3 nw_dst=10.1.0.2 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.3 nw_dst=10.1.0.3 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "priority=10000 dl_type=0x0800 nw_src=10.0.0.3 actions=normal" -O OpenFlow13

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.4 nw_dst=10.2.0.1 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.4 nw_dst=10.2.0.2 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.4 nw_dst=10.2.0.3 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "priority=10000 dl_type=0x0800 nw_src=10.0.0.4 actions=normal" -O OpenFlow13

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.5 nw_dst=10.2.0.1 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.5 nw_dst=10.2.0.2 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.5 nw_dst=10.2.0.3 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "priority=10000 dl_type=0x0800 nw_src=10.0.0.5 actions=normal" -O OpenFlow13

ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.6 nw_dst=10.2.0.1 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.6 nw_dst=10.2.0.2 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "dl_type=0x0800 nw_src=10.0.0.6 nw_dst=10.2.0.3 actions=mod_nw_tos:64,normal" -O OpenFlow13
ovs-ofctl add-flow s1 "priority=10000 dl_type=0x0800 nw_src=10.0.0.6 actions=normal" -O OpenFlow13

ovs-ofctl add-flow s1 "priority=5000 dl_type=0x0800 actions=drop" -O OpenFlow13

Klidně si testování ověřte, že je výsledek identický. Nicméně musíme už si tady trochu pohrát s prioritami (výchozí stav OVS je priorita 32k, takže naše 10000 a 5000 je nižší). V rámci tabulky už musíme používat více políček (v případě hardware tedy každý záznam má větší hardwarové nároky, například delší bitový TCAM – a to je velmi drahé). Ale co je myslím nejzajímavější – nejen, že pravidla jsou náročnější na počet polí, ale je jich celkově víc! 15 dohromady ve všech třech tabulkách versus 25. A tyto nůžky se budou rozevírat. Pokud by těch zdrojových IP bylo 1000 a potřebovali bychom 10 skupin a v každé 10 QoS situací – v jedenácti tabulkách budeme mít 1000 + 10 x 10 = 2000 záznamů. V jedné tabulce je to 10x 100 x 10 = 10 000 záznamů a to navíc složitějších na implementaci i úpravu (představte si třeba přesunutí zdrojové IP do jiné skupiny – jedna operace v prvním případě, deset změn v druhém).

Mám rád, když se člověk rychle dostane k nějakému jednoduchému příkladu a může rovnou něco vidět – možná už vás teď napadá, proč jsou tabulky důležité a jak jich využít. příště se na to podíváme systémově – jak se to dělá, kdy to dává smysl, ale hlavně – co na to hardware? Ostatně právě pro ten je to dost potřeba…
Series Navigation<< Malá učebnice OpenFlow (12) – metering a rate limitMalá učebnice OpenFlow (14) – tabulky a OpenFlow pipeline >>
Similar posts
  • L3 a kontejnery bez overlay: Project ... Část 6 z celkových 6 v seriálu L3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico prakticky (1) – architekturaL3 a kontejnery bez overlay: Project Calico prakticky (2) – rozjezdL3 a kontejnery bez overlay: Project Calico prakticky (3) – BGPL3 a kontejnery bez [...]
  • L3 a kontejnery bez overlay: Project ... Část 5 z celkových 6 v seriálu L3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico prakticky (1) – architekturaL3 a kontejnery bez overlay: Project Calico prakticky (2) – rozjezdL3 a kontejnery bez overlay: Project Calico prakticky (3) – BGPL3 a kontejnery bez [...]
  • HPE Networking na GitHub – skri... Zaměstnanci HPE publikovali zajímavé skripty a celé knihovny jako open source v licenci Apache2, tedy k volnému použití včetně jakýchkoli modifikací. https://github.com/HPENetworking/scriptsonly Obsah se bude jistě dost rozšiřovat… přidejte si záložku [...]
  • L3 a kontejnery bez overlay: Project ... Část 4 z celkových 6 v seriálu L3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico prakticky (1) – architekturaL3 a kontejnery bez overlay: Project Calico prakticky (2) – rozjezdL3 a kontejnery bez overlay: Project Calico prakticky (3) – BGPL3 a kontejnery bez [...]
  • L3 a kontejnery bez overlay: Project ... Část 3 z celkových 6 v seriálu L3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico praktickyL3 a kontejnery bez overlay: Project Calico prakticky (1) – architekturaL3 a kontejnery bez overlay: Project Calico prakticky (2) – rozjezdL3 a kontejnery bez overlay: Project Calico prakticky (3) – BGPL3 a kontejnery bez [...]

No Comments Yet

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *