[Berlin-wireless] IPv6 Routing-Konzepte fuer Freifunk

Alina Friedrichsen x-alina
Do Nov 26 01:37:14 CET 2009


Hi lynxis!

> ich bin gegen dualstack. da es meiner Meinung die Entwicklung nur
> behindert. Siehe die amd64 arch. das legacy stoert nur.

Naja, immerhin hat sich ja AMD64 gegen gegen IA-64 durchgesetzt. Fuer
letzteres liessen sich einfach keine Compiler schreiben. Aber hast schon
recht, die Global Descriptor Table sieht ziemlich durchloechert aus. ;)
Trotzdem gefaellt mir die AMD64-Architektur. Hab mal just4fun meinen
Assembler-Code angehaengt um die Kiste in den Long-Mode zu schalten. :)

> Ich halte 4to6 die bessere Moeglichkeit, da es erstmal schneller zu
> realisieren ist. 6to4 macht mehrere Probleme und loest ausserdem nicht
> das ip vergabe Problem.

Ja, normales IPv6- und IPv4-Routing parallel zu betreiben, halte ich
aber fuer eine Option fuer Mesh-Netzwerke in der Uebergangs-Phase.

> Es gibt btw. noch ein paar Probleme, wenn wir weiter denken in Richtung
> ipv6 only. Da kommt dann das nat Problem z.B. zum Tragen. Wir sollten
> (!) freifunk ohne NAT basteln. 
> 
> Wir haben ein Mesh mit vielen Nodes.
> Es gibt mehrere Nodes die als Gateway konfiguriert sind.
> jetzt schauen wir uns 2 Nodes davon an;
> - node GW ist gateway und hat dsl per ipv6
> - node CL ist client.
> 
> node GW : macht ein hna6 200/3
> node CL : moechte jetzt ins Internet und waehlt mit olsr die
> node GW aus. Nun braucht die node CL das ipv6 prefix vom DSL anschluss
> der node GW. Wie wird das kommuniziert ? Da gibt es jetzt mehrere
> Ansaetze. Meiner Meinung muesste das ganze stateful gemacht werden.
> Vielleicht dann per IPIP Tunnel (ipv6 natuerlich)

Ich bin mittlerweile zu dem Schluss gekommen, das wir einen
Tunnel-Daemon unterhalb des Routing-Daemons schreiben sollten, der dann
die IPv6 und IPv4-Tunnel ins Internet aufbaut. Und dann natuerlich auch
das oeffentliche Prefix aushandelt. In einen weiteren Schritt koennten
diese Verbindungen dann auch (endlich) verschluesselt werden.


> > Es gibt btw. noch ein paar Probleme, wenn wir weiter denken in
> Richtung
> > ipv6 only. Da kommt dann das nat Problem z.B. zum Tragen. Wir
> sollten
> > (!) freifunk ohne NAT basteln.
> NAT is bösartig. ;)

Full ACK! :)

Gruesse
Alina

-------------- nächster Teil --------------

MULTIBOOT_HEADER_FLAGS = 0x00000003
MULTIBOOT_HEADER_MAGIC = 0x1BADB002
MULTIBOOT_BOOTLOADER_MAGIC = 0x2BADB002

.extern panic
.globl _start

.text
_start:
	jmp 0f

# Multiboot-Header (fuer GRUB)
	.align 4
	.long MULTIBOOT_HEADER_MAGIC
	.long MULTIBOOT_HEADER_FLAGS
	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

# Testen, ob die ELF wirklich mit GRUB gebootet wurde
0:	cmp $MULTIBOOT_BOOTLOADER_MAGIC,%eax
0:	jne 0b

# Stack initialisieren
	movl $(stack + 4096),%esp

# ...
	movb $' ',0xb800a
	movb $' ',0xb800c

# Timer initialisieren
# 100 Hz (1193180 / 100 = 11932 = 0x2e9c)
	movb $0x34,%al		# Binary, Mode 2, LSB/MSB, SC 0
	outb %al,$0x43		# in das Steuerregister schreiben
	movb $0x9c,%al		# LSB in den
	outb %al,$0x40		# Zaehler 0 schreiben
	movb $0x2e,%al		# MSB in den
	outb %al,$0x40		# Zaehler 0 schreiben

############################################################################
# Testen welche Features die CPU unterstuetzt                              #
############################################################################

# Wird der CPUID-Befehl unterstuetzt?
# Er wird es, wenn sich das ID-Flag (Bit 21) aendern laest
	pushfl			# Die EFLAGS nach
	popl %eax		# EAX und
	movl %eax,%ebx		# EBX kopieren
	xorl $0x200000,%eax	# ID-Flag aendern
	pushl %eax		# und in die EFLAGS
	popfl			# zurueck schreiben
	pushfl			# Die EFLAGS erneut
	popl %eax		# nach EAX einlesen
	xorl %ebx,%eax		# und testen ob sich das
	jz 8f			# ID-Flag geaendert hat

# Ja, CPUID wird unterstuetzt
# Paranoia: Wird Funktion 1 unterstuetzt?
	xorl %eax,%eax		# Funktion 0
	cpuid			# CPUID
	cmpl $0,%eax		# CPUID Level in EAX
	je 8f			# EAX = 0?

# Feature Flags der CPU mit Funktion 1 einlesen
	movl $1,%eax		# Funktion 1
	cpuid			# CPUID
	movl %edx,%eax
	andl $0x40,%eax		# Wird PAE
	jz 0f			# unterstuetzt?
	movl $1,use_pae		# PAE benutzen
	movl %edx,%eax
0:	andl $0x2000,%eax	# Wird PGE
	jz 0f			# unterstuetzt?
	movl $1,use_pge		# PGE benutzen
	movl %edx,%eax
0:	andl $0x8,%eax		# Wird PSE
	jz 0f			# unterstuetzt?
	movl $1,use_pse		# PSE benutzen
0:	movb $'C',0xb8000
	jmp 9f

# Nein, CPUID wird nicht unterstuetzt
8:	movb $'c',0xb8000	# FIXME

############################################################################
# Paging initialisieren                                                    #
############################################################################

# Soll PAE benutzt werden?
9:	cmpl $0,use_pae
	je 4f

############################################################################
# Paging fuer PAE initialisieren                                           #
############################################################################

	movb $'A',0xb8002
# Page-Directory-Pointer-Table initialisieren (PAE)
	movl $pd,%edi		# Zeiger zur Page-Directory-
				# Pointer-Table nach EDI
	movl $pt,%eax		# Zeiger zum Page-Directory nach EAX
	orl $0x001,%eax		# Present-Flag
	movl %eax,0x00(%edi)	# 0 GB (zum booten)
	movl %eax,0x18(%edi)	# 3 GB (spaeteres Kernel-Segment)

# Page-Directory initialisieren (PAE)
	movl $pt,%edi		# Zeiger zum Page-
				# Directory nach EDI
	movl $0x083,%eax	# Present, Write und Page-Size Flag
	cmpl $0,use_pge		# PGE benutzen?
	je 0f
	orl $0x100,%eax		# Wenn ja, Global-Flag setzen
0:	movl %eax,0(%edi)	# 0 bis 2 MByte
	addl $0x200000,%eax	# 2 bis 4 MByte
	movl %eax,8(%edi)

	jmp 8f			# Paging aktivieren

############################################################################
# "Normales" Paging (ohne PAE) initialisieren                              #
############################################################################

# Page-Directory initialisieren (kein PAE)
4:	movb $'a',0xb8002

	movl $pd,%edi		# Zeiger zum Page-
				# Directory nach EDI
	movl $pt,%eax		# Zeiger zur Page-Table nach EAX
	orl $0x003,%eax		# Present und Write Flag
	movl %eax,0x000(%edi)	# 0 GB (zum booten)
	movl %eax,0xc00(%edi)	# 3 GB (spaeteres Kernel-Segment)

# Page-Table initialisieren (kein PAE)
	movl $pt,%edi		# Zeiger zur Page-Table nach EDI
	movl $0x003,%eax	# Present und Write Flags nach EAX
	cmpl $0,use_pge		# PGE benutzen?
	je 0f
	orl $0x100,%eax		# Wenn ja, Global-Flag setzen
0:	movl $1024,%ecx		# Anzahl der Page-Table Entrys
				# nach ECX
	cld			# 
0:	stosl			# Page-Table Entry erstellen
	addl $0x1000,%eax	# Naechste Page
	decl %ecx		# Laetzter Entry?
	jnz 0b

############################################################################
# Paging aktivieren                                                        #
############################################################################

# Paging aktivieren
8:		movb $'g',0xb8006
		movb $'-',0xb8008

	movl $pd,%eax		# Den Zeiger zum Page-
	movl %eax,%cr3		# Directory in CR3 laden

	cmpl $0,use_pae		# Soll PAE benutzt werden?
	je 0f
	movl %cr4,%eax		# Wenn ja, PAE-Flag
	orl $0x20,%eax		# in CR4 setzen
	movl %eax,%cr4
	jmp 1f			# PAE ignoriert PSE

0:	movb $'s',0xb8008
	cmpl $0,use_pse		# Soll PSE benutzt werden?
	je 1f
	movl %cr4,%eax		# Wenn ja, PSE-Flag
	orl $0x10,%eax		# in CR4 setzen
	movl %eax,%cr4
	movb $'S',0xb8008

1:	cmpl $0,use_pge		# Soll PGE benutzt werden?
	je 0f
	movl %cr4,%eax		# Wenn ja, PGE-Flag
	orl $0x80,%eax		# in CR4 setzen
	movl %eax,%cr4
	movb $'G',0xb8006

0:	movl %cr0,%eax		# Paging aktivieren
	orl $0x80000000,%eax	# 3... 2... 1...
	movl %eax,%cr0		# LIFT OFF! ;-)

	movb $'!',0xb8004

# Global Descriptor Table (GDT)
	lgdt gdt_descriptor
	lidt idt_descriptor
	ljmp $0x08,$0f
0:	movw $0x10,%ax
	movw %ax,%ds
	movw %ax,%es
	movw %ax,%ss
	movw %ax,%fs
	movw %ax,%gs

	movb $'?',0xb8004

	pushl $1234567890
	call panic

	hlt

.data

# Page-Directory oder Page-Directory-Pointer-Table in PAE
.align 4096
pd:	.fill 1024,4,0

# Page-Table oder Page-Directory in PAE
.align 4096
pae_pd:
pt:	.fill 1024,4,0

# Interrupt Descriptor Table (IDT)
.align 4
idt:
	.fill 256,8,0

.align 4
.word 0
idt_descriptor:
	.word 3*8-1
	.long 0xf0000000+idt

# Global Descriptor Table (GDT)
.align 4
gdt:
	.quad 0x0000000000000000	# 0x00 NULL
	.quad 0xf0c09a000000ffff	# 0x08 Kernel-Code 256 MB ab 0xf0000000
	.quad 0xf0c092000000ffff	# 0x10 Kernel-Data 256 MB ab 0xf0000000

.align 4
.word 0
gdt_descriptor:
	.word 3*8-1
	.long 0xf0000000+gdt

# Features die der Kernel benutzt
use_pae: .long 0
use_pge: .long 0
use_pse: .long 0
use_wp:  .long 0

# Kernel-Stack
	.comm stack,4096,4096
-------------- nächster Teil --------------

FREQ = 844
DIT = 50
DAH = 150
SPACE = 350

.globl panic
.text

# panic - haelt den Kernel bei einen schwerwiegenden Problem an
# und morst den Fehlercode (1. Parameter) mit Hilfe des PC-Speakers

# Morsealphabet:
# 1 .----  6 -....
# 2 ..---  7 --...
# 3 ...--  8 ---..
# 4 ....-  9 ----.
# 5 .....  0 -----

panic:
	cli			# Interrupts verbieten

# Timer 0 fuer die Kernel-Panic initialisieren
	movb $0x20,%al		# Binary, Mode 0, MSB, SC 0
	outb %al,$0x43		# in das Steuerregister schreiben

# Zahl zum spaeteren morsen in ihre Ziffern zerlegen
9:	movl $panic_buf,%edi	# Zeiger des Buffers nach EDI
	movl 4(%esp),%eax	# Zahl (1. Parameter) nach EAX
0:	xorl %edx,%edx		# Die oberen 32 Bit loeschen
	movl $10,%ebx		# Die Zahl durch 10 teilen
	divl %ebx		# Dividieren!
	movb %dl,(%edi)		# Die Ziffer (den Rest) speichern
	inc %edi		# Zeiger auf naechse Ziffer
	cmpl $0,%eax; jne 0b	# Naechste Ziffer?

# Die Ziffer (bzw. X) zum morsen aus dem Buffer holen
8:	cmp $panic_buf,%edi	# Wenn das die letzte Ziffer
	je 9b			# war, wieder von vorn beginnen
	dec %edi		# Naechste Ziffer
	movb (%edi),%dl		# Die Ziffer nach DL kopieren

# 5 mal piepen
	movb $5,%dh		# DH zaehlt dabei von 5 bis 0 runter

# Wenn X kleiner oder gleich 5 ist, wird X mal kurz gepiept
# und der rest von den 5 lang. Ist X dagegen groesser, wird
# X = X - 5 mal lang gepiept und der rest wird kurz gepiept.
	movb $DIT,%bl		# X mal kurz und
	movb $DAH,%bh		# den rest lang piepen,
	cmpb $5,%dl; jbe 7f	# wenn X <= 5 ist.
	subb $5,%dl		# ansonsten X = X - 5 und
	xchgb %bh,%bl		# X mal lang und den rest kurz piepen.

# Ton mit 844 Hz erzeugen
7:	inb $0x61,%al		# AND-Gate oeffnen
	orb $0x03,%al		# und Restart-Gate
	outb %al,$0x61		# auf aktiv setzen
	movb $0xb6,%al		# Binary, Mode 3, LSB/MSB, SC 2
	outb %al,$0x43		# in das Steuerregister schreiben
	movw $1193180/FREQ,%ax	# 844 Hz (1193180 / 844 = 1413)
	outb %al,$0x42		# LSB in den Zaehler 2 schreiben
	movb %ah,%al		# MSB in den
	outb %al,$0x42		# Zaehler 2 schreiben

# 50 oder 150 Ticks bei 100 Hz warten
# (also 0,5 oder 1,5 Sekunden)
	movb %bl,%cl		# Wurde schon X mal
	decb %dl		# gepiept?
	jns 0f			# Nein, wurde noch nicht
	movb %bh,%cl		# Ja, wurde schon
0:	movb $0x30,%al		# MSB in den
	outb %al,$0x40		# Zaehler 0 schreiben
1:	inb $0x40,%al		# Auf den
	cmpb $0,%al; jne 1b	# Zaehler 0 warten
	decb %cl; jnz 0b	# naechster Tick?

# Ton stillegen
	inb $0x61,%al		# AND-Gate schliessen
	andb $0xfc,%al		# und das Restart-Gate
	outb %al,$0x61		# deaktivieren

# 50, 150 oder 350 Ticks bei 100 Hz warten
# (also 0,5, 1,5 oder 3,5 Sekunden)
	movw $DIT,%cx		# War es ein normaler Piep?
	cmpb $1,%dh		# ???
	jne 0f			# Ja!
	movw $DAH,%cx		# Letzter Piep der Ziffer?
	cmpl $panic_buf,%edi	# ???
	jne 0f			# Ja!
	movw $SPACE,%cx		# Letzter Piep der Zahl!
0:	movb $0x30,%al		# MSB in den
	outb %al,$0x40		# Zaehler 0 schreiben
1:	inb $0x40,%al		# Auf den
	cmpb $0,%al; jne 1b	# Zaehler 0 warten
	decw %cx; jnz 0b	# naechster Tick?

# Naechster Piep
	decb %dh		# Letzter Piep der Ziffer?
	jnz 7b			# Nein!
	jmp 8b			# Ja!

# Buffer fuer die Kernel-Panic
	.comm panic_buf,10



Mehr Informationen über die Mailingliste Berlin