/* * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * \addtogroup uip * @{ */ /** * \file * Header file for routing table manipulation */ #ifndef UIP_DS6_ROUTE_H #define UIP_DS6_ROUTE_H #include "net/ipv6/uip.h" #include "net/nbr-table.h" #include "sys/stimer.h" #include "lib/list.h" #if UIP_CONF_IPV6_RPL #if UIP_CONF_IPV6_RPL_LITE == 1 #include "net/rpl-lite/rpl-conf.h" #else /* UIP_CONF_IPV6_RPL_LITE == 1 */ #include "net/rpl-classic/rpl-conf.h" #endif /* UIP_CONF_IPV6_RPL_LITE == 1 */ #endif #ifdef UIP_CONF_MAX_ROUTES #define UIP_MAX_ROUTES UIP_CONF_MAX_ROUTES #else /* UIP_CONF_MAX_ROUTES */ #if RPL_WITH_STORING #define UIP_MAX_ROUTES NETSTACK_MAX_ROUTE_ENTRIES #else #define UIP_MAX_ROUTES 0 #endif #endif /* UIP_CONF_MAX_ROUTES */ NBR_TABLE_DECLARE(nbr_routes); void uip_ds6_route_init(void); #ifndef UIP_CONF_UIP_DS6_NOTIFICATIONS #define UIP_DS6_NOTIFICATIONS (UIP_MAX_ROUTES != 0) #else #define UIP_DS6_NOTIFICATIONS UIP_CONF_UIP_DS6_NOTIFICATIONS #endif #if UIP_DS6_NOTIFICATIONS /* Event constants for the uip-ds6 route notification interface. The notification interface allows for a user program to be notified via a callback when a route has been added or removed and when the system has added or removed a default route. */ #define UIP_DS6_NOTIFICATION_DEFRT_ADD 0 #define UIP_DS6_NOTIFICATION_DEFRT_RM 1 #define UIP_DS6_NOTIFICATION_ROUTE_ADD 2 #define UIP_DS6_NOTIFICATION_ROUTE_RM 3 typedef void (* uip_ds6_notification_callback)(int event, uip_ipaddr_t *route, uip_ipaddr_t *nexthop, int num_routes); struct uip_ds6_notification { struct uip_ds6_notification *next; uip_ds6_notification_callback callback; }; void uip_ds6_notification_add(struct uip_ds6_notification *n, uip_ds6_notification_callback c); void uip_ds6_notification_rm(struct uip_ds6_notification *n); /*--------------------------------------------------*/ #endif /* Routing table */ #ifdef UIP_MAX_ROUTES #define UIP_DS6_ROUTE_NB UIP_MAX_ROUTES #else /* UIP_MAX_ROUTES */ #define UIP_DS6_ROUTE_NB 4 #endif /* UIP_MAX_ROUTES */ /** \brief define some additional RPL related route state and * neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */ #ifndef UIP_DS6_ROUTE_STATE_TYPE #define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t /* Needed for the extended route entry state when using ContikiRPL */ #define RPL_ROUTE_ENTRY_NOPATH_RECEIVED 0x01 #define RPL_ROUTE_ENTRY_DAO_PENDING 0x02 #define RPL_ROUTE_ENTRY_DAO_NACK 0x04 #define RPL_ROUTE_IS_NOPATH_RECEIVED(route) \ (((route)->state.state_flags & RPL_ROUTE_ENTRY_NOPATH_RECEIVED) != 0) #define RPL_ROUTE_SET_NOPATH_RECEIVED(route) do { \ (route)->state.state_flags |= RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \ } while(0) #define RPL_ROUTE_CLEAR_NOPATH_RECEIVED(route) do { \ (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \ } while(0) #define RPL_ROUTE_IS_DAO_PENDING(route) \ ((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_PENDING) != 0) #define RPL_ROUTE_SET_DAO_PENDING(route) do { \ (route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_PENDING; \ } while(0) #define RPL_ROUTE_CLEAR_DAO_PENDING(route) do { \ (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_PENDING; \ } while(0) #define RPL_ROUTE_IS_DAO_NACKED(route) \ ((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_NACK) != 0) #define RPL_ROUTE_SET_DAO_NACKED(route) do { \ (route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_NACK; \ } while(0) #define RPL_ROUTE_CLEAR_DAO_NACKED(route) do { \ (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_NACK; \ } while(0) #define RPL_ROUTE_CLEAR_DAO(route) do { \ (route)->state.state_flags &= ~(RPL_ROUTE_ENTRY_DAO_NACK|RPL_ROUTE_ENTRY_DAO_PENDING); \ } while(0) struct rpl_dag; typedef struct rpl_route_entry { uint32_t lifetime; struct rpl_dag *dag; uint8_t dao_seqno_out; uint8_t dao_seqno_in; uint8_t state_flags; } rpl_route_entry_t; #endif /* UIP_DS6_ROUTE_STATE_TYPE */ /** \brief The neighbor routes hold a list of routing table entries that are attached to a specific neihbor. */ struct uip_ds6_route_neighbor_routes { LIST_STRUCT(route_list); }; /** \brief An entry in the routing table */ typedef struct uip_ds6_route { struct uip_ds6_route *next; /* Each route entry belongs to a specific neighbor. That neighbor holds a list of all routing entries that go through it. The routes field point to the uip_ds6_route_neighbor_routes that belong to the neighbor table entry that this routing table entry uses. */ struct uip_ds6_route_neighbor_routes *neighbor_routes; uip_ipaddr_t ipaddr; #ifdef UIP_DS6_ROUTE_STATE_TYPE UIP_DS6_ROUTE_STATE_TYPE state; #endif uint8_t length; } uip_ds6_route_t; /** \brief A neighbor route list entry, used on the uip_ds6_route->neighbor_routes->route_list list. */ struct uip_ds6_route_neighbor_route { struct uip_ds6_route_neighbor_route *next; struct uip_ds6_route *route; }; /** \brief An entry in the default router list */ typedef struct uip_ds6_defrt { struct uip_ds6_defrt *next; uip_ipaddr_t ipaddr; struct stimer lifetime; uint8_t isinfinite; } uip_ds6_defrt_t; /** \name Default router list basic routines */ /** @{ */ uip_ds6_defrt_t *uip_ds6_defrt_head(void); uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval); void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt); uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr); uip_ipaddr_t *uip_ds6_defrt_choose(void); void uip_ds6_defrt_periodic(void); /** @} */ /** \name Routing Table basic routines */ /** @{ */ uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr); uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *next_hop); void uip_ds6_route_rm(uip_ds6_route_t *route); void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop); uip_ipaddr_t *uip_ds6_route_nexthop(uip_ds6_route_t *); int uip_ds6_route_num_routes(void); uip_ds6_route_t *uip_ds6_route_head(void); uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *); int uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr); /** @} */ #endif /* UIP_DS6_ROUTE_H */ /** @} */