FreeBSD networking question

Giorgos Keramidas keramida at ceid.upatras.gr
Fri Feb 1 01:22:50 EET 2008


Καλησπέρα,

Πήρα και το προσωπικό email, αλλά λόγω μικρής προτεραιότητας δεν πρόλαβα
να σου απαντήσω πιο πριν :/

On 2008-01-31 21:36, ithilgore <advent.cloud.strife at gmail.com> wrote:
> Kalhspera,
> thelw na asxolh8w me ta networking internals tou FreeBSD (kai giati
> oxi genika twn *BSD) gia peraiterw emba8unsh ston tomea tou low level
> networking kai 8a h8ela merikes sumboules :
> 
> 1) Exw ksekinhsei na diabazw to tcp-ip illustrated volume 2 (stevens) 
> alla anaferetai se sxetika palio implementation (4.4 BSD-Lite) pou
> shmainei oti afenos o kwdikas stis teleutaies dianomes einai safws pio
> periplokos kai pio megalos,

Από καλό βιβλίο ξεκίνησες, πάντως.  Μετά το ``TCP/IP Illustrated, Vol. I
και II'', ίσως έχει νόημα να δεις και το ``The Design & Implementation
of the FreeBSD Operating System''[1].  Είναι βασισμένο στο αρχικό
``Design & Implementation of the 4.4BSD Operating System'', και ο Kirk
McKusick είναι πάλι στους συγγραφείς.

[1] http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0201702452

Τώρα, σχετικά με τις διαφορές που έχει ένα πρόσφατο FreeBSD source tree
από το αρχικό kernel που σχολιάζει ο Stevens στα TCP/IP volumes, ίσως
έχει νόημα να διαβάζεις τον κώδικα από το FreeBSD 4.X *πριν* τις αλλαγές
που έγιναν για SMP support στον πυρήνα.

Το FreeBSD 4.X kernel χρησιμοποιεί τα ίδια splnet() και splxxx() calls
που περιγράφει ο Stevens για συγχρονισμό μεταξύ διαφόρων «ISR levels»
(ISR: interrupt service request).  Ο κώδικας έχει όντως διαφορές από το
4.4BSD -- είναι λογικό να υπάρχουν αλλαγές σχεδόν μιας δεκαετίας σε ένα
πυρήνα που συνεχώς εξελισσόταν από τότε που έγινε το αρχικό CVS import
του CSRG κώδικα στο CVS tree του FreeBSD.

Στο 4.X όμως βοηθάει ιδιαίτερα το ότι δεν υπάρχουν καθόλου τα διάφορα
commits που έγιναν για SMP support.  Δεν έχω μπροστά μου το TCP/IP Ill.
Vol 2 (κάπου το έχω δανείσει πάλι), αλλά ακόμα και από μια και μόνο
function φαίνεται ότι είναι πιο «απλός» ο κώδικας στο 4.X.  Στο τρέχον
RELENG_4 branch το αρχείο src/sys/netinet/tcp_usrreq.c έχει το εξής:

    146 /*
    147  * pru_detach() detaches the TCP protocol from the socket.
    148  * If the protocol state is non-embryonic, then can't
    149  * do this directly: have to initiate a pru_disconnect(),
    150  * which may finish later; embryonic TCB's can just
    151  * be discarded here.
    152  */
    153 static int
    154 tcp_usr_detach(struct socket *so)
    155 {
    156         int s = splnet();
    157         int error = 0;
    158         struct inpcb *inp = sotoinpcb(so);
    159         struct tcpcb *tp;
    160         TCPDEBUG0;
    161
    162         if (inp == 0) {
    163                 splx(s);
    164                 return EINVAL;  /* XXX */
    165         }
    166         tp = intotcpcb(inp);
    167         TCPDEBUG1();
    168         tp = tcp_disconnect(tp);
    169
    170         TCPDEBUG2(PRU_DETACH);
    171         splx(s);
    172         return error;
    173 }

Πρόσεξε ότι όντως χρησιμοποιεί τις ίδιες κλήσεις που περιγράφει ο
Stevens για αμοιβαίο αποκλεισμό μεταξύ των networking calls που
χειρίζονται τα TCP sockets: splnet() και splx().

Ο αντίστοιχος κώδικας στο 8.0-CURRENT, σήμερα, είναι:

    241 /*
    242  * pru_detach() detaches the TCP protocol from the socket.
    243  * If the protocol state is non-embryonic, then can't
    244  * do this directly: have to initiate a pru_disconnect(),
    245  * which may finish later; embryonic TCB's can just
    246  * be discarded here.
    247  */
    248 static void
    249 tcp_usr_detach(struct socket *so)
    250 {
    251         struct inpcb *inp;
    252
    253         inp = sotoinpcb(so);
    254         KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL"));
    255         INP_INFO_WLOCK(&tcbinfo);
    256         INP_LOCK(inp);
    257         KASSERT(inp->inp_socket != NULL,
    258             ("tcp_usr_detach: inp_socket == NULL"));
    259         tcp_detach(so, inp);
    260         INP_INFO_WUNLOCK(&tcbinfo);
    261 }

Οι κλήσεις splnet() και splx() έχουν αντικατασταθεί από πιο fine-grained
locks (βλ. INP_INFO_WLOCK(), INP_LOCK() και INP_INFO_WUNLOCK() κλήσεις
παραπάνω), αλλά αυτό κάνει τον κώδικα να είναι σημαντικά διαφορετικός
από αυτό που περιγράφει ο Stevens πλέον.

Κι αυτό για μια _πολύ_ απλή συνάρτηση, όπως η pr_usrreqs.pru_detach().

Μπορείς να φανταστείς εύκολα ότι οι διαφορές σε συναρτήσεις με πολύ
μεγαλύτερο μέγεθος ίσως να κάνουν το FreeBSD 8.0-CURRENT λίγο πιο
δύσκολο στην κατανόηση, αν προσπαθείς να διαβάσεις το Stevens και να
βρεις που υλοποιείται κάτι.

Γι αυτό, η δική μου συμβουλή είναι:

  (α) Διάβασε όντως το Stevens, αλλά

  (β) Αν κοιτάς και τον κώδικα ταυτόχρονα, χρησιμοποίησε το FreeBSD
      RELENG_4 branch (το τελευταίο 4.X release).

> einai sxetika duskolo na brw kapoia palia version pou na uposthrizei
> to networking code tou 4.4 bsd-lite me liges allages.  (To pio kontino
> pou brhka htan to FreeBSD 2.0.5).

Το FreeBSD 2.0.5 ίσως να είναι λίγο δύσκολο έως αδύνατον να τρέξει σε
μοντέρνο hardware (π.χ. λόγω ACPI, plug & play devices, disk controller
& motherboard chipset support, κλπ.).

> 2) Pio 8a htan to endedeigmeno approach gia na ksekinhsei kaneis to 
> megalo auto journey tou na asxolh8ei me ta internals (estw kai enos 
> merous tous) enos axanous se ektash susthmatos ?
>
> 3) Epipleon references/phges pou 8a boh8ousan sto sugekrimeno zhthma ?

Συνήθως βοηθάει το να έχεις κάποιο συγκεκριμένο στόχο, π.χ.:

    θέλω να βρω πώς υλοποιούνται τα flags ενός network interface, και να
    προσθέσω στην ifconfig(8) τη δυνατότητα να τυπώνει ένα flag του στυλ:

    ath0: flags=8802<UP,KERAMIDA,BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500

Αν βρεις πως γίνεται να υλοποιηθεί το flag «KERAMIDA» στον πυρήνα, ως
network interface property, πως αποθηκεύεται στη λίστα με τα interface
flags, πώς μπορεί η ifconfig να το ελέγξει από userlevel, και τέλος πώς
να το τυπώσει όταν δίνεται:

	ifconfig ath0

Θα έχεις μάθει ένα από τα βασικά κομμάτια του kernel & userland
interface: τον τρόπο με τον οποίο υλοποιείται ένα driver-independent
flag για τα interfaces.

Με τέτοια «mini-projects» θα μπορείς να εμβαθύνεις σε *λίγα* κομμάτια
του networking κάθε φορά, χωρίς να χρειάζεται να «γίνεις guru για τα
πάντα σε 21 μέρες» ή κάτι τέτοιο απίστευτο.

Μερικά άλλα πράγματα που βοηθάνε αρκετά είναι:

  * Ρώτα στη freebsd-net λίστα.  Οι άνθρωποι που γράφουν εκεί έχουν
    πολλή περισσότερη εμπειρία από εμένα,και θα σε βοηθήσουν σίγουρα με
    καλύτερο τρόπο

  * Βρες από το bug database κάποια εύκολα bugs, και προσπάθησε να δεις
    αν μπορείς να καταλάβεις:

      - γιατί είναι bugs

      - γιατί μπορεί να συμβαίνει αυτό το bug

      - πώς θα μπορούσε να φτιαχτεί

    Ότι κάνεις, μπορείς να το στέλνεις και στο bug database.  Αν είναι
    όντως καλή δουλειά, έτσι θα έχει πιθανότητες να ενσωματωθεί και στο
    ίδιο το FreeBSD.

Αυτά από εμένα, γι αρχή.

Καλό διάβασμα, και κυρίως...  Happy hacking :)




More information about the Linux-greek-users mailing list