/*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
u_int32_t rmx_rtt; /* estimated round trip time */
u_int32_t rmx_rttvar; /* estimated rtt variance */
u_int32_t rmx_pksent; /* packets sent using this route */
- u_int32_t rmx_filler[4]; /* will be used for T/TCP later */
+ u_int32_t rmx_state; /* route state */
+ u_int32_t rmx_filler[3]; /* will be used for T/TCP later */
};
/*
#ifdef BSD_KERNEL_PRIVATE
#include <kern/locks.h>
#include <net/radix.h>
+#include <net/if_llatbl.h>
+#include <sys/eventhandler.h>
+#include <net/if_dl.h>
/*
* Kernel resident routing tables.
*/
struct route {
/*
- * N.B: struct route must begin with ro_{rt,srcia,flags}
+ * N.B: struct route must begin with ro_{rt, lle, srcia, flags}
* because the code does some casts of a 'struct route_in6 *'
* to a 'struct route *'.
*/
struct rtentry *ro_rt;
+ struct llentry *ro_lle;
+
struct ifaddr *ro_srcia;
uint32_t ro_flags; /* route flags (see below) */
struct sockaddr ro_dst;
};
-#define ROF_SRCIF_SELECTED 0x1 /* source interface was selected */
+#define ROF_SRCIF_SELECTED 0x0001 /* source interface was selected */
+#if 0
+/* XXX These will be used in the changes coming in later */
+#define ROF_NORTREF 0x0002 /* doesn't hold reference on ro_rt */
+#define ROF_L2_ME 0x0004 /* dst L2 addr is our address */
+#define ROF_MAY_LOOP 0x0008 /* dst may require loop copy */
+#define ROF_HAS_HEADER 0x0010 /* mbuf already have its header prepended */
+#define ROF_REJECT 0x0020 /* Destination is reject */
+#define ROF_BLACKHOLE 0x0040 /* Destination is blackhole */
+#define ROF_HAS_GW 0x0080 /* Destination has GW */
+#endif
+#define ROF_LLE_CACHE 0x0100 /* Cache link layer */
#define ROUTE_UNUSABLE(_ro) \
((_ro)->ro_rt == NULL || \
(_ro)->ro_srcia = NULL; \
(_ro)->ro_flags &= ~ROF_SRCIF_SELECTED; \
} \
+ if ((_ro)->ro_lle != NULL) { \
+ LLE_REMREF((_ro)->ro_lle); \
+ (_ro)->ro_lle = NULL; \
+ (_ro)->ro_flags &= ~ROF_LLE_CACHE; \
+ } \
} while (0)
#define ROUTE_RELEASE_LOCKED(_ro) _ROUTE_RELEASE_COMMON(_ro, TRUE)
u_int32_t rtt_min; /* minimum RTT computed from history */
u_int32_t rtt_expire_ts; /* RTT history expire timestamp */
u_int8_t rtt_index; /* Index into RTT history */
+ /* Event handler context for the rtentrt */
+ struct eventhandler_lists_ctxt rt_evhdlr_ctxt;
+};
+
+enum {
+ ROUTE_STATUS_UPDATE = 1,
+ ROUTE_ENTRY_REFRESH,
+ ROUTE_ENTRY_DELETED,
+ ROUTE_LLENTRY_RESOLVED,
+ ROUTE_LLENTRY_UNREACH,
+ ROUTE_LLENTRY_CHANGED,
+ ROUTE_LLENTRY_STALE,
+ ROUTE_LLENTRY_TIMEDOUT,
+ ROUTE_LLENTRY_DELETED,
+ ROUTE_LLENTRY_EXPIRED,
+ ROUTE_LLENTRY_PROBED,
+ ROUTE_EVHDLR_DEREGISTER,
};
+extern const char * route_event2str(int route_event);
+
+typedef void (*route_event_fn) (struct eventhandler_entry_arg,
+ struct sockaddr *, int, struct sockaddr *, int);
+EVENTHANDLER_DECLARE(route_event, route_event_fn);
+
/*
* Synchronize route entry's generation ID with the tree's.
*/
((_rt)->rt_tree_genid != NULL && \
*(_rt)->rt_tree_genid != (_rt)->rt_genid)
+enum {
+ ROUTE_OP_READ,
+ ROUTE_OP_WRITE,
+};
+
+extern int route_op_entitlement_check(struct socket *, kauth_cred_t, int, boolean_t);
#endif /* BSD_KERNEL_PRIVATE */
#define RTF_UP 0x1 /* route usable */
#define RTF_DELCLONE 0x80 /* delete cloned route */
#define RTF_CLONING 0x100 /* generate new routes on use */
#define RTF_XRESOLVE 0x200 /* external daemon resolves name */
-#define RTF_LLINFO 0x400 /* generated by link layer (e.g. ARP) */
+#define RTF_LLINFO 0x400 /* DEPRECATED - exists ONLY for backward
+ compatibility */
+#define RTF_LLDATA 0x400 /* used by apps to add/del L2 entries */
#define RTF_STATIC 0x800 /* manually added */
#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */
#define RTF_NOIFREF 0x2000 /* not eligible for RTF_IFREF */
#define RTF_IFREF 0x4000000 /* route holds a ref to interface */
#define RTF_PROXY 0x8000000 /* proxying, no interface scope */
#define RTF_ROUTER 0x10000000 /* host is a router */
- /* 0x20000000 and up unassigned */
+#define RTF_DEAD 0x20000000 /* Route entry is being freed */
+ /* 0x40000000 and up unassigned */
+#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
#define RTF_BITS \
"\020\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE" \
"\10DELCLONE\11CLONING\12XRESOLVE\13LLINFO\14STATIC\15BLACKHOLE" \
"\25PINNED\26LOCAL\27BROADCAST\30MULTICAST\31IFSCOPE\32CONDEMNED" \
"\33IFREF\34PROXY\35ROUTER"
+#define IS_DIRECT_HOSTROUTE(rt) \
+ (((rt)->rt_flags & (RTF_HOST | RTF_GATEWAY)) == RTF_HOST)
/*
* Routing statistics.
*/
short rts_newgateway; /* routes modified by redirects */
short rts_unreach; /* lookups which failed */
short rts_wildcard; /* lookups satisfied by a wildcard */
+ short rts_badrtgwroute; /* route to gateway is not direct */
};
/*
extern void ctrace_record(ctrace_t *);
#define RT_LOCK_ASSERT_HELD(_rt) \
- lck_mtx_assert(&(_rt)->rt_lock, LCK_MTX_ASSERT_OWNED)
+ LCK_MTX_ASSERT(&(_rt)->rt_lock, LCK_MTX_ASSERT_OWNED)
#define RT_LOCK_ASSERT_NOTHELD(_rt) \
- lck_mtx_assert(&(_rt)->rt_lock, LCK_MTX_ASSERT_NOTOWNED)
+ LCK_MTX_ASSERT(&(_rt)->rt_lock, LCK_MTX_ASSERT_NOTOWNED)
#define RT_LOCK(_rt) do { \
rt_lock(_rt, FALSE); \
extern boolean_t rt_ifa_is_dst(struct sockaddr *, struct ifaddr *);
extern struct sockaddr *sa_copy(struct sockaddr *, struct sockaddr_storage *,
unsigned int *);
+
+/*
+ * The following is used to enqueue work items for route events
+ * and also used to pass route event while walking the tree
+ */
+struct route_event {
+ struct rtentry *rt;
+ /*
+ * There's no reference taken on gwrt.
+ * We only use it to check whether we should
+ * point to rt_gateway or the embedded rt_addr
+ * structure.
+ */
+ struct rtentry *gwrt;
+ union {
+ union sockaddr_in_4_6 _rtev_ipaddr;
+ struct sockaddr_dl _rtev_lladdr;
+ char _rtev_addr_bytes[DLIL_SDLMAXLEN];
+ } rt_addr;
+ uint32_t route_event_code;
+ eventhandler_tag evtag;
+};
+
+#define rtev_ipaddr rt_addr._rtev_ipaddr
+#define rtev_lladdr rt_addr._rtev_lladdr
+#define rtev_addr_bytes rt_addr._rtev_addr_bytes
+
+extern void route_event_init(struct route_event *p_route_ev, struct rtentry *rt,
+ struct rtentry *gwrt, int route_ev_code);
+extern int route_event_walktree(struct radix_node *rn, void *arg);
+extern void route_event_enqueue_nwk_wq_entry(struct rtentry *, struct rtentry *,
+ uint32_t, eventhandler_tag, boolean_t);
#endif /* BSD_KERNEL_PRIVATE */
#endif /* _NET_ROUTE_H_ */