]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/route.h
xnu-4903.241.1.tar.gz
[apple/xnu.git] / bsd / net / route.h
index 4ceed51bfa612419516223039695cb574b27c218..141381e0ae3d5a467b813106b11f4606decae957 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -83,7 +83,8 @@ struct rt_metrics {
        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 */
 };
 
 /*
@@ -102,6 +103,9 @@ struct route_old {
 #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.
@@ -123,17 +127,30 @@ struct rt_reach_info;
  */
 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 ||                                        \
@@ -154,6 +171,11 @@ struct route {
                (_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)
@@ -210,8 +232,31 @@ struct rtentry {
        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.
  */
@@ -227,6 +272,12 @@ struct rtentry {
        ((_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 */
@@ -239,7 +290,9 @@ struct rtentry {
 #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 */
@@ -259,8 +312,10 @@ struct rtentry {
 #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" \
@@ -268,6 +323,8 @@ struct rtentry {
        "\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.
  */
@@ -277,6 +334,7 @@ struct      rtstat {
        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 */
 };
 
 /*
@@ -450,10 +508,10 @@ typedef struct ctrace {
 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);                                            \
@@ -593,5 +651,37 @@ extern void route_copyout(struct route *, const struct route *, size_t);
 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_ */