routing local IP addresses

Giorgos Keramidas keramida at ceid.upatras.gr
Thu May 24 16:16:41 EEST 2007


On 2007-05-24 15:14, basilis <bts at the.forthnet.gr> wrote:
>Giorgos Keramidas wrote:
>>>> _______
>>>> |      |eth0 (10.0.0.1)
>>>> |      |--------------------------------- |----------|
>>>> |      |                                  | HUB      |      
>>>> | PC   |eth1 (10.0.0.2)                   |          |
>>>> |      |--------------------------------- |----------|
>>>> |      |
>>>> |______|
>>>>
>>>> Θέλω να κάνω το εξής: Να κάνω ping από την κάρτα eth0 (ΙΡ
>>>> 10.0.0.1) στο ΙΡ 10.0.0.2 (eth1) ΑΛΛΑ τα πακέτα να περνάνε
>>>> από το HUB/SWITCH και οχι να γίνεται εσωτερικά η
>>>> δρομολόγηση. Καταλαβαίνω οτι αυτό δεν είναι κάτι που
>>>> χρειάζεται σε normal δίκτυα αλλά θα εκτιμούσα αν κάποιος έχει
>>>> καμία ιδέα.
>>>
>>> route add -host 10.0.0.2 eth0
>>>
>>> Αυτό δεν σου παίζει?
>> 
>> Bzzzzzzzt, wrong.  Και υπάρχει _λόγος_ που δεν παίζει...
> 
> Για εξήγα το θείο, να μαθαίνουμε κι εμείς οι νιούφηδες! ;-)

Όταν στείλεις ένα πακέτο από userlevel εφαρμογή, αυτό θα περάσει
μέσα από τον πυρήνα.  Η διαδρομή που ακολουθεί ένα πακέτο είναι
κάτι σαν αυτό το σχήμα (κάπως απλοποιημένο):


                        ,---------------------------------.
                        |            userlevel            |
                        |           application           |
                        `---------------------------------'
                            ||                 ||
                  socket    ||		       || socket2
           ,----------------'|		       ||
           |,----------------'		       ||
           ||                                  ||            USER SPACE
  . . . . .|| . . . . . . . . . . . . . . . . .|| . . . . . . . . . . .
           ||                                  ||          KERNEL SPACE
           ||                                  ||
           |`-----------.                      |`-----------.
           |            |                      |            |
    eth0   |            |               eth1   |            |         
   ,-------|------------|--------.     ,-------|------------|--------.
   |       |            |        |     |       |            |        |
   | +-----|-----+ +----|------+ |     | +-----|-----+ +----|------+ |
   | |     v     | |    |      | |     | |     v     | |    |      | |
   | |           | |    |      | |     | |           | |    |      | |
   | | out queue | | in queue  | |     | | out queue | | in queue  | |
   | +-----------+ +-----------+ |     | +-----------+ +-----------+ |
   |   /                ^        |     |   /                ^        |
   |  /                 |        |     |  /                 |        |
   |  |                 |        |     |  |                 |        |
   |  |                 |        |     |  |                 |        |
   |  |                 |      direct     |                 |        |
   |  |                 . . . . . . . . . .                 |        |
   |  |                 |      dispatch   |                 |        |
   |  |                 |        |     |  |                 |        |
   |  | driver        intr       |     |  | driver        intr       |
   |  | output        handler    |     |  | output        handler    |
   |  | kthread         |        |     |  | kthread         |        |
   |  |                 |        |     |  |                 |        |
   |  |                 |        |     |  |                 |        |
   |  v                 |        |     |  v                 |        |
   | +-------------------------+ |     | +-------------------------+ |
   | |         physical        | |     | |         physical        | |
   | |          device         | |     | |          device         | |
   | +-------------------------+ |     | +-------------------------+ |
   `-----------------------------'     `-----------------------------'
                 ^                                     ^
                 |                                     |
                 |                                     |
                 `-------------------------------------'
                                 external
                                   link

Κάθε φορά που στέλνεις ένα πακέτο που πρέπει να καταλήξει μέσω
του "physical link" (του καλωδίου ή της κεραίας για ασύρματα
δίκτυα) σε ένα άλλο μηχάνημα, ο πυρήνας κάνει κάτι σαν:

  - Αντιγράφει τα δεδομένα του userspace application σε ένα
    kernel buffer (ή κάνει απλά map την ίδια περιοχή μνήμης στον
    πυρήνα)

  - Βάζει το εξερχόμενο πακέτο στην 'out queue' του σωστού interface

  - Επιστρέφει σε userspace

  - Κάποια στιγμή αργότερα το 'driver output kthread' γίνεται
    schedule σε κάποια cpu.

  - Το νέο thread παίρνει το πακέτο από την εξερχόμενη ουρά και
    το προωθεί (συνήθως με hardware specific τρόπο) στον driver
    του interface.

  - Ο driver του interface μέσω hardware specific τρόπων στέλνει
    το πακέτο στο physical link

  - Στην άλλη πλευρά του physical link, φτάνει ένα εισερχόμενο
    πακέτο.

  - Ο απέναντι driver αντιγράφει τα δεδομένα του πακέτου σε ένα
    νέο kernel buffer και τον δίνει τον interrupt handler

  - Ο interrupt handler του device γίνεται schedule σε κάποια cpu

  - Παίρνει το πακέτο και το τοποθετεί στην input queue του interface

  - Τα υψηλότερα layer του TCP/IP βγάζουν το πακέτο από το input
    queue και το περνούν στο userspace application.

Αυτό κοστίζει σε χρόνο, bandwidth, και είναι *ΑΡΓΟ* σε σχέση με
αυτό που κάνει τώρα ο πυρήνας.

  - Μόλις ένα πακέτο για 'local address' εμφανιστεί στο output
    queue ενός interface, το ίδιο ακριβώς buffer βγαίνει από την
    ουρά, την ώρα που τρέχει το ίδιο ακριβώς kernel thread, και
    μπαίνει στην input ουρά του 'destination interface' (βλ. το
    'direct dispatch' κομμάτι στο διάγραμμα παραπάνω).

Καμία σχέση σε ταχύτητα, scheduling overhead, memory allocation
overhead, και πιθανότητα 'καταστροφής' των δεδομένων από βλακείες
του physical link (π.χ. καλώδιο που έχει πρόβλημα) ;-)




More information about the Linux-greek-users mailing list