taming openbsd network stack dragons by martin pieuchot

25
Taming OpenBSD Network Stack Dragons Martin Pieuchot [email protected] EuroBSDcon, Sofia September 2014

Upload: eurobsdcon

Post on 16-Jul-2015

153 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Taming OpenBSD Network Stack Dragons

Martin [email protected]

EuroBSDcon, Sofia

September 2014

Page 2: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Taming OpenBSD Network Stack Dragons

sys/net/radix mpath.c

/*

* Stolen from radix.c rn addroute().

* This is nasty code with a certain amount of magic and dragons.[...]

*/

2 of 25

Page 3: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Agenda

Motivation

Representing Addresses & Routes

Stack Metamorphosis

Where are we now?

Conclusion

3 of 25

Page 4: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Agenda

Motivation

Representing Addresses & Routes

Stack Metamorphosis

Where are we now?

Conclusion

4 of 25

Page 5: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Motivation

1. Give a talk at EuroBSDCon

2. Enjoy code from the 80’s

3. Make it easier to run it in parallel� Execute (some parts of) the forwarding path on > 1 CPUs� Cleaning from the “top”: ioctl and ipforward paths

4. Adapt it to a Plug & Play world

5. Development process: commit early, revert, fix, commit

5 of 25

Page 6: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Agenda

Motivation

Representing Addresses & Routes

Stack Metamorphosis

Where are we now?

Conclusion

6 of 25

Page 7: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

What do we use addresses for?

Identify peers

� Who is the receiver?

� Who is the sender?

Direct packets

� Where is the destination? IPv4 header

7 of 25

Page 8: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Journey of a packet

Input For me?

Forward?

no

Deliveryes

Select interface

yes

OutputSend

Identify

� None

� None

� None

� None

Direct

� None

� None

� None

8 of 25

Page 9: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Representation of an address

Interface address (ifa)

struct ifaddr {

struct sockaddr *ifa_addr; /* address of interface */

struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */

#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */

struct sockaddr *ifa_netmask; /* used to determine subnet */

struct ifnet *ifa_ifp; /* back-pointer to interface */

TAILQ_ENTRY(ifaddr) ifa_list; /* list of addresses for interface */

[...]

};

9 of 25

Page 10: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Global data structures

Interface without address

Int. List

ifp

lladdr

if_sadl ifa_ifp

RB-tree

10 of 25

Page 11: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Global data structures

Interface with an address

Int. List

ifp

lladdr

if_sadl ifa_ifp

ifa

ifa_ifp

rtentry

Routing Table

RB-tree

Addr. List

11 of 25

Page 12: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

When are they accessed?

Input For me?

Forward?

no

Deliveryes

Select interface

yes

OutputSend

ip input

� RB-tree

� Addr. List

� Int. List

ip forward

� Routing table*

ip output

� Routing table*

� Addr. List

� Int. List

12 of 25

Page 13: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Agenda

Motivation

Representing Addresses & Routes

Stack Metamorphosis

Where are we now?

Conclusion

13 of 25

Page 14: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Global lists

1. Get rid of link-layer address lookups

2. Use local (per ifp) lists instead of global ones

3. Or simply rewrite the code without the lookup

4. Otherwise (in the process context) use the Interface List

Some modified functionscarp set addr(), ether output(), ifa ifwithnet(), ifa ifwithroute(), IFP TO IA(),in localaddr(), in pcbbind(), in selectsrc(), ipv4 input(), ip output(), m cldrop(),rip usrreq(), rt getifa()...

14 of 25

Page 15: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Interface list

ifa ifwithaddr(), ifa ifwithdstaddr() and ifa ifwithnet()

1981: One address per interface (struct ifnet)

1985: Per interface list of addresses (struct ifaddr)

2010: Global RB-Tree of addresses

1985: Global list of addresses per protocol (i.e. struct in ifaddr)

1999: KAME uses the routing table to forward or deliver

15 of 25

Page 16: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Routing table

� Use the routing table for address lookups� Consolidate KAME’s “loobpack” hack

RTF LOCAL For each configured addressRTF BROADCAST For every IPv4 subnet

� Only one global structure� Easier than maintaining coherency between various structures� Needs some love to be accessed in parallel

� Not slower/faster than the actual RB-tree

16 of 25

Page 17: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Protocol multicast addresses

ifp

ifa0

ifa1 mcast

ifa2

all hosts

mcast

Addr. List

OpenBSD 5.4

ifp

ifa0 all hosts

ifa1

ifa2

mcast

mcast

Addr. List

OpenBSD 5.5

17 of 25

Page 18: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Related changes

� The link-layer address has been remove from all the lists� No need to move this information to the routing table� Many many dragons in this code

� SO DONTROUTE is no longer supported� No option to bypass the routing table

� Interface indexes are now unique� Avoid dangling pointers

� inet ntop() replaces inet ntoa() in the kernel

18 of 25

Page 19: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Agenda

Motivation

Representing Addresses & Routes

Stack Metamorphosis

Where are we now?

Conclusion

19 of 25

Page 20: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Global data structures

Interface with an address

ifa

ifp

ifa_ifp

Int. List

rtentry

Routing Table

20 of 25

Page 21: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

When are they accessed?

Input For me?

Forward?

no

Deliveryes

Select interface

yes

OutputSend

ip input

� Routing table*

� None

� None

ip forward

� None

ip output

� Routing table*

� None

� None

21 of 25

Page 22: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Well, we’re almost there

� Diff to kill the RB-tree is on tech@

� RTF LOCAL routes still points to lo0

� Still doing 2 lookups in the forwarding case

Hopefully integrated for OpenBSD 5.7

22 of 25

Page 23: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Agenda

Motivation

Representing Addresses & Routes

Stack Metamorphosis

Where are we now?

Conclusion

23 of 25

Page 24: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Conclusion

� Refactoring 30 years old code is hard� But we have a pretty good history

� Very few people care because� It’s not a “feature”� There’s no visible speed gain� Changes always find some dragons

� Understanding what you’re changing is important� Future developers won’t hate you (or not that much)

� Still plenty of dragons

24 of 25

Page 25: Taming OpenBSD Network Stack Dragons by Martin Pieuchot

Questions?

Slides on http://www.openbsd.org/papers/

25 of 25