projectsroutingproposal:api

This is an old revision of the document!


Project/routing API

There are 2 main functions in lltable used to lookup lladdr data by external callers: int arpresolve(ifnet *ifp, int is_gw, mbuf *m, sockaddr *dst, u_char *desten, uint32_t *pflags) and the corresponding

int nd6_resolve(ifnet *ifp, int is_gw, mbuf *m, sockaddr *dst, u_char *desten, uint32_t *pflags)

is_gw argument

is_gw is passed to alter error message (EHOSTUNREACH instead of EHOSTDOWN). Lltable should not known anything about errors specifics. This can (and already is) being lazy-computed in some of packet output routines (D4102 changed that for ether_output()).

Broadcast/Multicast

Broadcast/Multicast is handled inside <arp|nd_>resolve(). This is conceptually wrong since this mapping is dependent on actual protocol set being used. De-facto each output routine handles it itself instead of calling _resolve() routines.

Sockaddr usage

There is very little sense in passing sockaddr as a key to the lookup routine for particular family. Especially because internally lltable have been using addresses instead of sockaddrs since r286624.

Given that, set of 2 new lookup functions is proposed: int lle4_lookup(ifnet *ifp, mbuf *m, struct in_addr dst, u_char *desten, uint32_t *pflags) and the corresponding

int lle6_lookup(ifnet *ifp, mbuf *m, struct in6_addr *dst, u_char *desten, uint32_t *pflags)

More details in DXXXX.

There are numerous amount of functions and wrappers to perform rtentry lookup. Two most notable are: struct rtentry *rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags, u_int fibnum) Returns locked and refcounted struct rtentry or NULL. void rtalloc_ign_fib(struct route *ro, u_long ignore, u_int fibnum) This one saves rtentry into passed ro→ro_rt and unlocks it.

Locking rtentry

Rte is locked and refcounted to ensure that the caller can safely dereference rtentry fields. The important fact here is that refcounting rtentry does not protect you from rt_ifp ifnet being destroyed after lookup. The only refcount that is hold by rtentry is rt_ifa (which, in turn, is just a structure not refcounting anything itself). So, refcounting rtentry just gives you stable storage, nothing more. Theoretically, rtentry could be copied to stack structure, but it practice it's not feasible (sizeof(struct rtentry) > 200 bytes on amd64, with prefix/gw allocated separately, netmask pointer from radix, etc..).

Too complex

Instead of getting pre-computed result consumer has to alter the results itself: if RTF_GATEWAY is set then.., check which MTU is less: rt_mtu or ifp→ifp_mtu or rt_ifa→ifa_ifp→ifp_mtu or IN6_LINKMTU(), etc. Having individual rtentries returned also prevents (good) multipath implementation. Again, since most of callers are af-specific, passing sockaddrs as a key adds additional complexity. (especially with IPv6 LLA). Also, exposing all internals makes it really hard to hack routing code. Most consumers need very basic things: check if ifp is “right”, get mtu, etc. Current API is an overkill for most of the tasks.

Goals

  • Provide pre-computed easy to-use result
  • Use compact on-stack structures
  • Provide different functions for different tasks varying in terms of provided information and speed
  • Be multipath-ready from day 1.

Functions

  • projectsroutingproposal/api.1452941854.txt.gz
  • Last modified: 2016/01/16 10:57
  • by AlexanderChernikov