Differences

This shows you the differences between two versions of the page.

Link to this comparison view

rl:teme:tema1_sw [2025/10/13 23:53]
vlad_andrei.badoiu
rl:teme:tema1_sw [2025/10/31 18:11] (current)
radu.mantu
Line 1: Line 1:
 <​hidden>​ <​hidden>​
-====== Tema 1 - Implementare Switch ​(0.8p) ​======+====== Tema 1 - Implementare Switch ======
  
 === Lectura recomandata === === Lectura recomandata ===
  
   * Tema ar trebui facuta doar dupa ce ati parcurs **Cursul si laboratorul de VLAN & STP**   * Tema ar trebui facuta doar dupa ce ati parcurs **Cursul si laboratorul de VLAN & STP**
- 
   * [[https://​beta.computer-networking.info/​syllabus/​default/​protocols/​lan.html?​highlight=spanning%20tree%20protocol#​ethernet-switches|Ethernet Switches]]   * [[https://​beta.computer-networking.info/​syllabus/​default/​protocols/​lan.html?​highlight=spanning%20tree%20protocol#​ethernet-switches|Ethernet Switches]]
   * [[https://​www.youtube.com/​watch?​app=desktop&​v=japdEY1UKe4|STP Animation]]   * [[https://​www.youtube.com/​watch?​app=desktop&​v=japdEY1UKe4|STP Animation]]
Line 16: Line 15:
 Mininet este un simulator de rețele ce folosește în simulare implementări reale Mininet este un simulator de rețele ce folosește în simulare implementări reale
 de kernel, switch și cod de aplicații. Pentru a nu avea probleme de compatibilitate,​ vom rula pe Linux aceasta tema. de kernel, switch și cod de aplicații. Pentru a nu avea probleme de compatibilitate,​ vom rula pe Linux aceasta tema.
-Va recomandam ​[[https://​ctipub-my.sharepoint.com/:​u:/​g/​personal/​mihai_dumitru2201_upb_ro/​ETNaykK4iaJPgatE6_46N1ABa1UqgauDXbALmNfyhfWLig?​e=lnIHAx|aceasta ​masina virtuala de ubuntu]].+Vom folosi urmatoarea ​[[https://​ctipub-my.sharepoint.com/:​u:/​g/​personal/​mihai_dumitru2201_upb_ro/​ETNaykK4iaJPgatE6_46N1ABa1UqgauDXbALmNfyhfWLig?​e=lnIHAx|masina virtuala de ubuntu]].
  
 <code bash> <code bash>
Line 77: Line 76:
 În contextul suportului VLAN apare următoarea terminologie:​ un port de tip **trunk** este un port prin care pot fi transmise cadre din mai multe VLAN-uri și se află între două switch-uri, în timp ce un port de tip **access** este un port care conectează un host la switch. În contextul suportului VLAN apare următoarea terminologie:​ un port de tip **trunk** este un port prin care pot fi transmise cadre din mai multe VLAN-uri și se află între două switch-uri, în timp ce un port de tip **access** este un port care conectează un host la switch.
  
-{{:rl:teme:vlans-33-768x532.png?400|}}+{{ :rl:teme:t1_new_topo.png?500 | }} 
 + 
 +<​html><​center><​i>​ 
 +Topologia implementată în mininet. Valorile numerice scrise în roșu pe link-uri reprezinta VID-ul tip 802.1Q.<​br>​ 
 +Partiționarea rețelei pe baza VID-ului extins (unde se ia în calcul adresa MAC) este reprezentată prin culorile sistemelor H0-H5.<​br>​ 
 +Citiți restul cerinței pentru mai multe detalii. 
 +</​i></​center></​html>​
  
 <​note>​ <​note>​
-VLAN-ul este configurat la nivelul portului de switch, nu la nivelul unui host, chiar dacă în multe reprezentări grafice stațiile sunt ilustrate ca făcând parte dintr-un VLAN.+În mod normal, ​VLAN-ul este configurat la nivelul portului de switch, nu la nivelul unui host, chiar dacă în multe reprezentări grafice stațiile sunt ilustrate ca făcând parte dintr-un VLAN
 + 
 +În acest task, vom încălca acest principiu.
 </​note>​ </​note>​
  
-Protocolul [[https://​www.ietf.org/​rfc/​rfc2674.txt|IEEE 802.1Q]] este folosit pentru a introduce sistemul de marcare VLAN (VLAN tagging) în Ethernet, sub forma unei extensii a antetului (header-ului) Ethernet. În imaginea de mai jos putem observa că au fost introduși 4 octeți (bytes). De interes ​pentru noi este câmpul VID pe 12 biți, ce reprezintă identificatorul VLAN-ului din care cadrul face parte. +Protocolul [[https://​www.ietf.org/​rfc/​rfc2674.txt|IEEE 802.1Q]] este folosit pentru a introduce sistemul de marcare VLAN (VLAN tagging) în Ethernet, sub forma unei extensii a antetului (header-ului) Ethernet. În imaginea de mai jos putem observa că au fost introduși 4 octeți (bytes). De înteres ​pentru noi este câmpul VID pe 12 biți, ce reprezintă identificatorul VLAN-ului din care cadrul face parte. 
-De acum înainte, când ne vom referi la un pachet cu header-ul 802.1Q, vom înțelege că este vorba despre un cadru Ethernet plus acești 4 byți.+De acum înainte, când ne vom referi la un pachet cu header-ul 802.1Q, vom înțelege că este vorba despre un cadru Ethernet plus acești 4 octeți.
  
-{{ :​rl:​teme:​ethernet_802.png?​600 |}}+{{ :​rl:​teme:​ethernet_802.png?​600 | }}
  
 {{ :​rl:​teme:​tag_format.png?​400 | }} {{ :​rl:​teme:​tag_format.png?​400 | }}
  
-Switch-ul cand **primeste** un cadru de pe orice interfata va comuta cadrul ​mai departe astfel:+Noi vom implementa un sistem custom de VLAN tagging similar cu 802.1Q. Acesta se va distinge prin două aspecte: 
 +  * **TPID**-ul va fi //​0x8200//​. 
 +  ​Biții ​**PCP** și **DEI** for fi reutilizați ca extensie pentru câmpul **VID**. Acesta din urmă va contine in continuare tag-ul ​de VLAN configurat ​pe portul switch-ului,​ dar cei mai semnificativi biți din **TCI** vor lua valoarea sumei [[https://​en.wikipedia.org/​wiki/​Nibble|nibble]]-urilor adresei MAC a host-ului asociat access port-ului. Overflow-ul sumei poate fi ignorat.
  
-  * cu header-ul 802.1Q dacă se transmite pe un port de tip trunk (către un switch). De notat că, în funcție de portul sursă, cadrul primit poate fi sau nu în format 802.1Q. De exemplu, dacă este un cadru primit pe un port trunk, atunci acesta va fi în format 802.1Q. În schimb, dacă este un cadru primit ​de pe o interfață de tip access, acesta nu va avea header 802.1Q, iar implementarea noastră de switch va trebui să îl adauge. +Switch-ul cand **primește** ​un cadru de pe orice interfata ​va comuta cadrul mai departe astfel:
-  * fără header-ul 802.1Q dacă se transmite pe o interfață de tip access și VLAN ID-ul este egal cu cel al interfeței de pe care a venit (către un host direct conectat la switch, parte a aceluiași VLAN)+
  
-Nu vom comuta cadrele atunci când VLAN ID port destinație !VLAN ID cadru.+  * Cu header-ul nostru custom (802.1Q-like) dacă se transmite pe un port de tip trunk (către un switch). De notat că, în funcție de portul sursă, cadrul primit poate fi sau nu să conția deja acest tag. De exemplu, dacă este un cadru primit pe un port trunk, atunci acesta va fi tagged. În schimb, dacă este un cadru primit de pe o interfață de tip access, acesta nu va avea header-ul //EtherType=0x8200//, iar implementarea noastră de switch va trebui să îl adauge. 
 +  * Fără header-ul custom dacă se transmite pe o interfață de tip access. Comutarea pachetului este condiționată de verificarea câmpului **VID extins**. VID-ul stocat în cadru trebuie sa fie egal cu cel configurat pe portul switch-ului,​ iar cei mai semnificativi 4 biți din TCI trebuie să coincidă cu suma nibbleurilor adresei MAC a host-ului conectat pe portul respectiv. Pentru a simplifica implementarea,​ extensia de 4 biți poate fi ignorată daca frame-ul este multicast sau dacă adresa MAC a host-ului incă nu a fost adaugată in tabela CAM.
  
-Stațiile din simulare rulează Linux, iar stiva de networking din Linux face VLAN filtering, ​pentru ​a nu pierde eticheta VLAN (VLAN tag), vom folosi pentru TPID valoarea ​**0x8200** în loc de **0x8100**. Practic vom avea o implementare custom de 802.1q. Câmpurile PCP și DEI vor fi setate la valoarea 0.+<note tip> 
 +Un exemplu de calcul a extensiei ​de VID pentru ​host-ul H5 cu MAC-ul **de:​ad:​be:​ef:​09:​01**:​ 
 + 
 +<​code>​ 
 +(0xd + 0xe + 0xa + 0xd + 0xb + 0xe + 0xe + 0xf + 0x9 + 0x1) & 0xf = 114 & 0xf = 0x2 
 +</​code>​ 
 + 
 +Deoarece ​VLAN ID-ul clasic configurat pe switch este **2**, VID-ul extins va fi **0x2002**. 
 +</​note>​
  
 **Atentie, nu uitati ca dimensiunea cadrului creste cu 4 bytes** **Atentie, nu uitati ca dimensiunea cadrului creste cu 4 bytes**
Line 111: Line 128:
 ==== The Spanning Tree Protocol(802.1d) ==== ==== The Spanning Tree Protocol(802.1d) ====
  
-Protocolul Spanning Tree (Spanning Tree Protocol - STP) este un protocol distribuit utilizat de switch-uri pentru a reduce topologia rețelei la un arbore de acoperire, astfel încât să nu existe bucle în topologie. În figura de mai jos, rețeaua conține multiple bucle care trebuie eliminate pentru a permite switch-urilor Ethernet să transmită cadre fără riscul inundării rețelei cu trafic redundant. ​Dupa mai multe runde (secunde pentru noi), toti participantii ​(switch-urile) vor converge ​catre un lider (root bridge). ​Acesta este un algoritm de tip leader election.+Protocolul Spanning Tree (Spanning Tree Protocol - STP) este un protocol distribuit utilizat de switch-uri pentru a reduce topologia rețelei la un arbore de acoperire, astfel încât să nu existe bucle în topologie. În figura de mai jos, rețeaua conține multiple bucle care trebuie eliminate pentru a permite switch-urilor Ethernet să transmită cadre fără riscul inundării rețelei cu trafic redundant, care ar conduce la colapsul rețeleiDupă mai multe runde (secunde pentru noi), toți participanții ​(switch-urile) vor converge ​către ​un lider (root bridge). ​STP folosește ​un algoritm de tip leader election.
  
 {{ :​rl:​teme:​stp.png?​500 |}} {{ :​rl:​teme:​stp.png?​500 |}}
  
 <​note>​ <​note>​
-Pentru a înțelege mai bine acest protocol, vom simula în Packet Tracer o topologie cu trei switch-uri. Vom studia cadrele BPDU (Bridge Protocol Data Units), evidențiate cu roz în simulator, care sunt transmise periodic de către switch-uri.+Pentru a înțelege mai bine acest protocol, ​înainte de a începe tema vom simula în Packet Tracer o topologie cu trei switch-uri. Vom studia cadrele BPDU (Bridge Protocol Data Units), evidențiate cu roz în simulator, care sunt transmise periodic de către switch-uri.
 </​note>​ </​note>​
  
-Implementarea noastră va fi una simplificată: ​vom avea un singur proces STP pentru toate VLAN-urile, iar scopul este de a bloca link-urile care conduc la formarea de bucle. Cadrele transmise în cadrul protocolului se numesc Bridge Protocol Data Units (BPDU) și conțin trei informații importante: identificatorul switch-ului rădăcină (root bridge ID - 64 biți), identificatorul switch-ului expeditor (sender bridge ID - 64 biți) și costul drumului până la rădăcină (root path cost - 64 biți). Switch-ul rădăcină (root bridge) este switch-ul cu identificatorul cel mai mic.+In cadrul temei vom implementa o varianta ​de STP numita **Poli STP sau PSTP**.
  
-Algoritmul simplificat este descris în pseudocodul de mai jos. În implementarea noastră, un port de switch poate avea două stări: **Blocking** și **Listening**. În starea Listening, portul funcționează normal ​pentru ​comutarea cadrelor. La pornire, fiecare switch se consideră Root Bridge și își setează ​toate porturile în starea Listeningdeoarece acestea sunt considerate porturi **designated** ​porturi ​care au costul cel mai mic catre Root Bridge.+Astfelvom avea un singur proces STP pentru toate VLAN-urileiar scopul este de a bloca link-urile care conduc la formarea de bucleVom avea doua tipuri de cadre trimise in cadrul protocolului:​
  
-<note warning>​ +  * Hello Protocol Data Units (HPDU)Este un pachet trimis ​la fiecare secundă de fiecare switchÎl vom folosi ca formă de verificare a faptului ​că un link este activ. În această implementare doar vom trimite aceste cadre, nu ne interesează funcționalitatea de marcare a unui link ca fiind nefuncțional**Acesta este trimis pe toate porturile, si cele trunk, si cele catre hosts**
-În implementarea algoritmului ne interesează doar porturile de tip trunk, deoarece doar prin acestea se pot forma bucleAstfel, orice referință ​la porturi în pseudocod se referă la legăturile trunkLegăturile ​tre hosts (porturile de tip access) rămân în starea listening pe toată durata ​funcționării switch-ului. +
-</​note>​+
  
-<code Python>​ +  * Poli Protocol Data Units (PPDU) și vor conține trei informații importanteidentificatorul switch-ului rădăcină ​(root bridge ID - 64 biți), identificatorul ​switch-ului expeditor (sender ​bridge ID - 64 biți) și costul drumului până la rădăcină (root path cost - 64 biți)Switch-ul rădăcină (root bridge) este switch-ul cu identificatorul cel mai mic.
-Initialize: +
-    # Punem pe block-ing port-urile trunk pentru ca +
-    # doar de acolo pot aparea bucle. Port-urile catre +
-    # statii sunt pe deschise ​(e.g. designated) +
-    for each trunk port on the switch+
-        Set port state to BLOCKING +
-     +
-    # In mod normal ​bridge ID este format si din switch.mac_address +
-    # pentru simplitate vom folosi doar priority value ce se gaseste in +
-    # configuratie +
-    own_bridge_ID =  switch.priority_value +
-    root_bridge_ID = own_bridge_ID +
-    root_path_cost = 0 +
-     +
-    # daca portul devine ​root bridge ​setam porturile ca designated +
-    if own_bridge_ID == root_bridge_ID:​ +
-        For each port on the bridge: +
-            Set port state to DESIGNATED_PORT +
-</​code>​+
  
-La fiecare secunda, daca suntem root bridge, vom trimite un pachet BPDU. 
  
-<code Python>​ +**Structura cadrelor PPDU.** Cadrele PPDU folosesc encapsularea 802.2 Logical Link Control header. Mai jos putem vedea structura unui cadru PPDU.
-Every 1 second: +
-    if switch is root: +
-        Send BPDU on all trunk ports with: +
-            root_bridge_ID = own_bridge_ID +
-            sender_bridge_ID = own_bridge_ID +
-            sender_path_cost = 0 +
-</​code>​+
  
-În cazul în care am primit un pachet de tip BPDU, dacă 
-acesta are un BID (Bridge ID) mai mic decât al nostru, atunci switch-ul de la 
-care am primit acest pachet devine root bridge pentru noi. Mai mult, 
-vom retransmite propriul nostru BPDU actualizat pe toate celelalte porturi. 
  
-<code Python>​ +   Size (bytes) 6        6       ​2 ​          ​3 ​           4           31 
-On receiving a BPDU: +              ​DST_MAC|SRC_MAC|LLC_LENGTH|LLC_HEADER|PPDU_HEADER|PPDU_CONFIG
-    if BPDU.root_bridge_ID < root_bridge_ID:​ +
-        root_bridge_ID = BPDU.root_bridge_ID +
-        # Vom adauga 10 la cost pentru ca toate link-urile sunt de 100 Mbps +
-        root_path_cost = BPDU.sender_path_cost + 10  +
-        root_port = port where BPDU was received +
-         +
-        if we were the Root Bridge: +
-            set all interfaces not to hosts to blocking except the root port  ​+
  
-        +LLC_LENGTH este dimensiunea totala a cadrului, inclusiv dimensiunea PPDULLC_HEADER are urmatoarea structura:
-        if root_port state is BLOCKING: +
-            Set root_port state to LISTENING +
-         +
-        Update and forward this BPDU to all other trunk ports with: +
-            sender_bridge_ID = own_bridge_ID +
-            sender_path_cost = root_path_cost +
-   +
-     Else if BPDU.root_bridge_ID == root_bridge_ID: +
-        If port == root_port and BPDU.sender_path_cost + 10 < root_path_cost:​ +
-            root_path_cost = BPDU.sender_path_cost + 10+
  
-        Else If port != Root_Port: +  Size             ​1 ​                                 1                           1 
-            # Verifica daca portul ar trebui trecut pe designated. +    DSAP (Destination Service Access Point)|SSAP (Source Service Access Point)|Control
-            # Designated inseamna ca drumul catre root este prin +
-            # acest switch. Daca am bloca acest drum, celelalte +
-            # switch-uri nu ar mai putea comunica cu root bridge. +
-            # Nota: in mod normal ar trebui sa stocam ultimul BPDU +
-            # de pe fiecare port ca sa calculam designated port. +
-            if BPDU.sender_path_cost > root_path_cost:​ +
-                If port is not the Designated Port for this segment: +
-                    Set port as the Designated Port and set state to LISTENING+
  
-    Else if BPDU.sender_bridge_ID == own_bridge_ID+Pentru a identifica protocolul PPDU, DSAP si SSAP vor fi 0x42Pentru control vom pune 0x03. 
-        Set port state to BLOCKING + 
-    Else+Structura Poli PPDU_HEADER este urmatoare
-        ​Discard ​BPDU + 
-       +  Size (bytes) 
-    if own_bridge_ID == root_bridge_ID+       ​2 ​             1                 ​1 ​               4 
-        ​For each port on the bridge: +  Protocol ID|Protocol Version|PPDU Type|Sequence Number| 
-            ​Set ​port as DESIGNATED_PORT + 
-</code>+Detalii de implementare pentru câmpuri
 + 
 +  * Protocol ID - Vom folosi 0x0002 pentru PPDU Protocol 
 +  * PPDU Type (1 byte): Vom folosi TCN BPDU 
 +  * Sequence Number (4 bytes): Numărul de secvență. Fiecare cadru PPDU va avea acest număr incrementat. Vom porni numărul de  secvență de la 0. Valoarea va fi modulo 100. Astfel, primul cadru trimis la prima cuantă de timp va avea numărul de secvență 0, al doilea va avea numărul de secvență 1, al 100-lea va avea numărul de secvență 99, iar al 101-lea va avea numărul de secvență 0. 
 + 
 + 
 +Structura PPDU_CONFIG este urmatoare
 + 
 +  Size (bytes) 
 +       ​1 ​         8              4            8       ​2 ​       2           ​2 ​       2           ​2 ​      
 +    flags|root bridge ID|root path cost|bridge id|port id|message age|max age|hello time|forward delay| 
 + 
 +  * Vom presupune fiecare link ca fiind de 100 Mbps, costul pe link va fi conform celor descris in curs pentru STP (pentru switch-uri cu legaturi normale, nu rapide). Este folosit in calculul root path cost. 
 +  * bridge ​id va fi calculat conform descrierii din [[https://​ocw.cs.pub.ro/​courses/​_media/​rl/​courses/​rl05-optimizare-lan-25-26.pdf|curs]]. Prioritatea este disponibila in config. 
 +  * Max age va fi setat pe maximul posibil din specificatia de 802.1D-2004 
 +  * Hello Time va fi setat pe valoarea recomandata din 802.1D-2004 
 +  * Forward Delay va fi setat pe valoarea minima din 802.1D-2004 
 +  * port id este construit conform standardului 802.1D. Prioritatea este disponibila in config. 
 +  * flags il setam pe 0 
 +  * message age este setat pe 0 
 +  ​ 
 +Nu uitati, in networking folosim Big Endian.
  
 <​note>​ <​note>​
-Pentru ​simplitatevom presupune ca switch-urile ​nu se pot strica.+Pentru ​a fi punctat acest subpunctcadrele trebuie să respecte indicațiile de mai sus. Pentru fiecare valoare din cadru care nu este exact specificată în enunț (e.g., pentru cele unde se specifică că valoarea este conform 802.1D-2004),​ va trebui să argumentați decizia și să includeți o referință. Fie un link, fie un PDF în arhivă în directorul sources. Sursa trebuie să includă locația exactă în document, fie prin pagină, fie prin numele secțiunii etc. Checker-ul verifică doar funcționalitatea,​ nu și respectarea cerințelor de fond.
 </​note>​ </​note>​
  
 +Pentru a vizualiza protocolul nostru custom, vom folosi un [[https://​mika-s.github.io/​wireshark/​lua/​dissector/​2017/​11/​04/​creating-a-wireshark-dissector-in-lua-1.html|dissector de Wireshark]]. Pentru a il incarca, va trebui sa il puneti in
 +///​usr/​lib/​x86_64-linux-gnu/​wireshark/​plugins//​ pe VM (gasiti path-ul pe un setup custom in Wireshark -> About -> Folders -> Global LUA Plugins). Va trebui sa dati restart la Wireshark.
  
-**Structura cadrelor BPDU.** Cadrele BPDU folosesc encapsularea 802.2 Logical Link Control header. Figura de mai jos prezinta un astfel de cadru: 
  
-{{ :​rl:​teme:​screenshot_from_2023-10-28_17-10-27.png?400 |}}+Cadrele PPDU sunt identificate prin adresa multicast MAC destinatie descrisa in standardul 802.1D.
  
-Următorul +**Pachetele trimise trebuie sa fie conforme si sa fie identificate corect ​de catre disectorul de PSTP din Wireshark**
-[[https://​techhub.hpe.com/​eginfolib/​networking/​docs/​switches/​5980/​5200-3921_l2-lan_cg/​content/​499036672.htm|articol]] prezintă pe scurt structura lor. [[https://​wiki.wireshark.org/​uploads/​8d3d0627231ab1e2fa5d3fe8be2390a7/​stp.pcap|Aici]] gasiti o captura ​de trafic STP.+
  
-   Size (bytes) 6        6       ​2 ​          ​3 ​           4           31 +{{:​rl:​teme:​pstp.png?​300|}}
-              DST_MAC|SRC_MAC|LLC_LENGTH|LLC_HEADER|BPDU_HEADER|BPDU_CONFIG+
  
-LLC_LENGTH este dimensiunea totala a cadrului, inclusiv dimensiunea BPDU. LLC_HEADER are 
-urmatoarea structura: 
  
-  Size             ​1 ​                                 1                           1 +In pseudocodul de mai jos este descrisa o posibila varianta a algoritmului descris la curs.  In aceasta implementare,​ un port de switch poate avea două stări: **Blocking** și **Forwarding**. In mod normal, tranzitia catre Forwarding este realziata astfel: Blocking -> Listening -> Learning -> Forwarding pentru a evita buclele in timpul schimbarii topologiei. Totusi, noi o sa trecem direct la forwarding. În starea forwarding, portul funcționează normal pentru comutarea cadrelor. La pornire, fiecare switch se consideră Root Bridge și își setează toate porturile în starea Forwarding. De asemenea, avem urmatoarele roluri pe porturi:
-    DSAP (Destination Service Access Point)|SSAP (Source Service Access Point)|Control+
  
-Pentru a identifica protocolul STPDSAP si SSAP vor fi 0x42. Pentru control vom pune 0x03+  * Designated - când două switch-uri sunt conectateswitch-ul cu costul mai mic către root bridge va avea portul său ca port desemnatEste un port prin care trimitem PPDU-uri către un switch care are un cost mai mare către root bridge 
-Structura BPDU Config este urmatoare:+  * Root - portul catre root bridge cu costul cel mai mic  
 +  * Non-Designated - port blocat pentru a evita buclele
  
-    uint8_t ​ flags; +<note warning> 
-    ​uint8_t ​ root_bridge_id[8];​ +În implementarea algoritmului ne interesează doar porturile de tip trunk, deoarece doar prin acestea se pot forma bucle. Astfel, orice referință la porturi în pseudocod se referă la legăturile trunk. Legăturile către hosts (porturile de tip access) rămân în starea listening pe toată durata funcționării switch-ului. 
-    ​uint32_t root_path_cost;​ +</​note>​
-    uint8_t ​ bridge_id[8];​ +
-    uint16_t port_id; +
-    uint16_t message_age;​ +
-    uint16_t max_age; +
-    uint16_t hello_time;​ +
-    uint16_t forward_delay;​+
  
-Cum toate switch-urile ​implementeaza protocolul scris de noiputeti folosi fie aceasta structurafie va definiti propria voastra reprezentare.+<code Python>​ 
 +Initialize:​ 
 +    # Initial ​toate porturile sunt blocate, pentru a nu avea bucle. 
 +    # Similar cu ce putem observa in PackeTracer,​ cand link-urile 
 +    # catre switch-uri nu sunt imediat active 
 +    set_ports_state(BLOCKING) 
 +     
 +    # Initialfiecare switch se considera root bridge 
 +    own_bridge_ID =  compute_bridge_id(prioritymac) 
 +    root_bridge_ID = own_bridge_ID 
 +    root_path_cost = 0 
 +     
 +    set_all_ports_role(DESIGNATED) 
 +</​code>​
  
-**Cadrele BPDU sunt identificate prin adresa multicast MAC destinatie01:80:​C2:​00:​00:​00.**+La fiecare secundadaca suntem root bridge, vom trimite un cadru PPDU. 
 +De asemenea, trebuie sa trimitem la fiecare secunda cadrul HPDU. 
 +<code Python>​ 
 +Every 1 second: 
 +    if root_bridge_ID == own_bridge_ID 
 +        Send PPDU on all ports 
 +    else 
 +        Send PPDU on all DESIGNATED ports 
 +    Send HPDU 
 +</​code>​
  
 +<code Python>
 +On receiving a PPDU on port P:
 +    ​
 +    # Am descoperit un nou root bridge
 +    if PPDU.root_bridge_ID < root_bridge_ID:​
 +        # Actualizam detalile noului root bridge, precum root_port
 +        set_new_root_bridge()
 +        # Ajusteaza rolurile si starile tuturor porturilor pentru a
 +        # surprinde schimbarea de root bridge
 +        adjust_all_port_roles_and_states()
 +   
 +    else if PPDU.root_bridge_ID == root_bridge_ID:​
 +        # Am descoperit o cale mai buna catre root bridge
 +        if PPDU.sender_path_cost + LINK_COST < root_path_cost:​
 +            # Ajustam root_path_cost si root_port
 +            update_root_bridge()
 +            adjust_all_port_roles_and_states()
 +            ​
 +        ​
 +        # Am primit un PPDU cu un cost mai mare
 +        else if PPDU.sender_path_cost + LINK_COST > root_path_cost:​
 +            set P role to DESIGNATED
 +            set P state to FORWARDING
 +            ​
 +        else # Atat eu cat si switch-ul de la care am primit PPDU-ul avem acelasi cost
 +            if PPDU.sender_bridge_ID < own_bridge_ID:​
 +                set P role to ROOT
 +                set P state to FORWARDING
 +            else:
 +                set P role to DESIGNATED
 +                set P state to FORWARDING
 +</​code>​
  
 +<​note>​
 +Pentru simplitate, vom presupune ca switch-urile nu se pot strica.
 +</​note>​
 +
 +<​note>​
 +Pentru a primi punctaj pe acest subpunct, va trebui să includeți în arhivă un fișier **state_machine.drawio** care să includă reprezentarea state machine-ului implementat pentru PSTP. Vom folosi [[https://​app.diagrams.net/​|draw.io]] pentru asta.
 +</​note>​
  
 ==== API ==== ==== API ====
Line 296: Line 328:
 Nu exista API pentru citirea configuratiei. Nu exista API pentru citirea configuratiei.
 </​note>​ </​note>​
 +
 ==== Cerinte ==== ==== Cerinte ====
  
Line 306: Line 339:
   * **Procesul de comutare (30p)**. Va trebui să implementați funcționalitatea descrisă în secțiunea **Procesul de Comutare**. Pentru acest exercițiu nu este nevoie să implementați funcționalitatea referitoare la VLAN sau STP. Pentru a evita buclele, vom porni doar switch-urile 0 și 1.   * **Procesul de comutare (30p)**. Va trebui să implementați funcționalitatea descrisă în secțiunea **Procesul de Comutare**. Pentru acest exercițiu nu este nevoie să implementați funcționalitatea referitoare la VLAN sau STP. Pentru a evita buclele, vom porni doar switch-urile 0 și 1.
   * **VLAN (30p)**. Vom implementa funcționalitatea de Virtual Local Area Networks (VLANs). Fișierele de configurație ale switch-urilor se găsesc în directorul **configs**. Pentru a evita buclele, vom porni doar switch-urile 0 si 1.   * **VLAN (30p)**. Vom implementa funcționalitatea de Virtual Local Area Networks (VLANs). Fișierele de configurație ale switch-urilor se găsesc în directorul **configs**. Pentru a evita buclele, vom porni doar switch-urile 0 si 1.
-  * ** STP (40p)**. In acest exercițiu vom introduce si switch-ul 2, care va determina apariția unei bucle. Se cere implementarea protocolului STP simplificat,​ descris in enunț, pentru a evita trimiterea pachetelor la infinit. ​+  * ** STP (40p)**. In acest exercițiu vom introduce si switch-ul 2, care va determina apariția unei bucle. Se cere implementarea protocolului STP simplificat,​ descris in enunț, pentru a evita trimiterea pachetelor la infinit.
  
-Pentru a fi punctata o tema, in README trebuie prezentata soluția voastră pe scurt. 
-<​note>​ 
-Este foarte important să folosiți Wireshark pentru verificarea corectitudinii implementării. 
-</​note>​ 
  
-<​note>​ +Pentru a fi punctată o temă, arhiva trebuie să conțină câte un screenshot relevant pentru fiecare exercițiu ​în care să apară numele vostru (e.g. cu un echo), una sau mai multe ferestre de Wireshark și unul sau mai multe terminale care să dovedească rularea manuală a funcționalității relevanteFiecare screenshot este insotit si de o explicație în README. De asemenea, în README trebuie să documentați deciziile de design (e.g., cum ați stocat stările în STP), dificultățile întâmpinate și cum le-ați rezolvat, optimizările aduse dacă este cazul, și o secțiune de auto-evaluare a implementării. 
-Puteți scrie implementarea ​în Python ​sau C/C++Daca lucrati in C/C++ va trebui sa schimbati regula ​de rulare ​switch-ului din **Makefile**. + 
-</​note>​+> Screenshot-urile vor fi incluse în root-ul arhivei cu numele ​**ex1.jpg**, **ex2.jpg** și **ex3.jpg**
  
 ==== Testare ==== ==== Testare ====
rl/teme/tema1_sw.1760388786.txt.gz · Last modified: 2025/10/13 23:53 by vlad_andrei.badoiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0