Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| projectsroutingproposal:api [2016/01/16 12:50] – AlexanderChernikov | projectsroutingproposal:api [2016/01/17 08:25] (current) – AlexanderChernikov | ||
|---|---|---|---|
| Line 3: | Line 3: | ||
| ===== LLTABLE ===== | ===== LLTABLE ===== | ||
| There are 2 main functions in lltable used to lookup lladdr data by external callers: | 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)// | + | < |
| + | int arpresolve(ifnet *ifp, int is_gw, mbuf *m, sockaddr *dst, u_char *desten, uint32_t *pflags) | ||
| + | </code> | ||
| + | |||
| + | and the corresponding | ||
| + | |||
| + | < | ||
| + | int nd6_resolve(ifnet *ifp, int is_gw, mbuf *m, sockaddr *dst, u_char *desten, uint32_t *pflags) | ||
| + | </code> | ||
| ==== API Problems ==== | ==== API Problems ==== | ||
| Line 17: | Line 24: | ||
| ==== New API ==== | ==== New API ==== | ||
| Given that, set of 2 new lookup functions is proposed: | 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)// | + | < |
| + | int in_resolve_lla(ifnet *ifp, mbuf *m, struct in_addr dst, u_char *desten, uint32_t *pflags) | ||
| + | int in6_resolve_lla(ifnet *ifp, mbuf *m, struct in6_addr *dst, u_char *desten, uint32_t *pflags) | ||
| + | </code> | ||
| - | More details in DXXXX. | + | More details in [[https:// |
| ===== Routing ===== | ===== Routing ===== | ||
| Line 34: | Line 43: | ||
| ==== API problems ==== | ==== API problems ==== | ||
| === Locking rtentry === | === 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, | + | 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, | ||
| === Caller complexity === | === Caller complexity === | ||
| 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-> | 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-> | ||
| Line 47: | Line 58: | ||
| * Use compact on-stack structures | * Use compact on-stack structures | ||
| * Provide different functions for different tasks varying in terms of provided information and speed | * Provide different functions for different tasks varying in terms of provided information and speed | ||
| + | * Have per-AF functions and use addresses instead of sockaddr | ||
| * Be multipath-ready from day 1. | * Be multipath-ready from day 1. | ||
| * Hide all of the internals avoiding passing rtentries to any data/ | * Hide all of the internals avoiding passing rtentries to any data/ | ||
| - | === Functions === | + | === Data path functions === |
| - | == Data path == | + | |
| This set of functions return minimal amount of data needed to forward a packet (or verify some basic data), e.g. next-hop data. | This set of functions return minimal amount of data needed to forward a packet (or verify some basic data), e.g. next-hop data. | ||
| Nexthop consists of interface, mtu, flags, data to prepend or next-hop address. Right now next-hop size is 64 bytes (leaving about 40 bytes for pre-calculated prepend data like ethernet header). | Nexthop consists of interface, mtu, flags, data to prepend or next-hop address. Right now next-hop size is 64 bytes (leaving about 40 bytes for pre-calculated prepend data like ethernet header). | ||
| Line 59: | Line 70: | ||
| - Different lookup algorithms _are_ required: patricia is not so well suited for long IPv6 keys. Additionally, | - Different lookup algorithms _are_ required: patricia is not so well suited for long IPv6 keys. Additionally, | ||
| - | Actual functions | + | Source: [[https:// |
| + | |||
| + | Actual functions | ||
| + | == fibX_lookup_nh_basic() == | ||
| + | The simplest form of lookup, no references are provided. | ||
| < | < | ||
| Line 107: | Line 122: | ||
| </ | </ | ||
| - | **The simplest form of lookup, no references are provided.** | + | == fibX_lookup_nh_ext() == |
| + | More advanced one: IPv4 source address is returned, some pointers can be referenced if required. Right now internal referencing/ | ||
| < | < | ||
| Line 133: | Line 149: | ||
| uint64_t | uint64_t | ||
| }; | }; | ||
| + | void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4) | ||
| /* | /* | ||
| Line 155: | Line 172: | ||
| uint64_t | uint64_t | ||
| }; | }; | ||
| + | void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6) | ||
| + | |||
| </ | </ | ||
| - | **More advanced one: IPv4 source address is returned, some pointers can be referenced if required. Right now internal referencing/dereferencing is a no-op (which is exactly like current rtalloc/rte implementation).** | + | == fibX_lookup_prepend() == |
| + | Actual functions used for forwarding. Passing | ||
| < | < | ||
| + | /* | ||
| + | * Performs lookup in IPv4 table fib @fibnum. | ||
| + | * Assumes @ro-> | ||
| + | * In case of successful lookup ro-> | ||
| + | * appropriate interface info and full L2 header to prepend or | ||
| + | * nhop address. If route does not contain gateway, or gateway is unreachable, | ||
| + | * NHF_L2_INCOMPLETE flag and gateway address is stored into nh-> | ||
| + | * If @hh is not NULL, additional nexthop data is stored there. | ||
| + | * | ||
| + | * Returns 0 on success. | ||
| + | */ | ||
| + | int fib4_lookup_prepend(uint32_t fibnum, struct in_addr dst, uint32_t flags, uint32_t flowid, struct route *ro, struct nhop4_helper *hh); | ||
| + | /* Non-recursive nexthop */ | ||
| + | struct nhop_prepend { | ||
| + | uint16_t | ||
| + | uint8_t | ||
| + | uint8_t | ||
| + | uint16_t | ||
| + | struct ifnet *nh_lifp; | ||
| + | struct ifnet *nh_aifp; | ||
| + | union { | ||
| + | char nh_data[MAX_PREPEND_LEN]; | ||
| + | struct in_addr | ||
| + | struct in6_addr nh6_addr;/* IPv4 gw address */ | ||
| + | }; | ||
| + | }; | ||
| + | void fib4_free_prepend(struct nhop_prepend *pnh); | ||
| </ | </ | ||
| - | **Actual | + | === Control plane functions |
| + | Some consumers want to check if particular prefix exists, or check actual rte flags, which cannot be achieved using fibX functions. Luckily, all(most) there consumers are control-plane ones (arp/nd code). | ||
| + | |||
| + | == rib_lookup() == | ||
| + | The goal is to provide real per-rte information and, if possible, avoid direct rte access. This is accomplished by using //struct rt_addrinfo// | ||
| + | |||
| + | < | ||
| + | /* | ||
| + | * Lookups up route entry for @dst in RIB database for fib @fibnum. | ||
| + | * Exports entry data to @info using rt_exportinfo(). | ||
| + | * | ||
| + | * if @flags contains NHR_REF, refcouting is performed on rt_ifp. | ||
| + | | ||
| + | * | ||
| + | * Returns 0 on success. | ||
| + | * Returns ENOENT for lookup failure, ENOMEM for export failure. | ||
| + | */ | ||
| + | int rib_lookup_info(uint32_t fibnum, const struct sockaddr *dst, uint32_t flags, uint32_t flowid, struct rt_addrinfo | ||
| + | void rib_free_info(struct rt_addrinfo | ||
| + | </ | ||