summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_arcsubr.c5
-rw-r--r--sys/net/if_ethersubr.c4
-rw-r--r--sys/net/if_fddisubr.c5
-rw-r--r--sys/net/if_fwsubr.c9
-rw-r--r--sys/net/if_iso88025subr.c8
-rw-r--r--sys/net/if_loop.c8
-rw-r--r--sys/net/radix_mpath.c61
-rw-r--r--sys/net/radix_mpath.h1
-rw-r--r--sys/net/route.c17
-rw-r--r--sys/net/route.h28
10 files changed, 77 insertions, 69 deletions
diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c
index 4944e97..16adba4 100644
--- a/sys/net/if_arcsubr.c
+++ b/sys/net/if_arcsubr.c
@@ -113,9 +113,8 @@ arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
error = 0;
#if defined(INET) || defined(INET6)
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
switch (dst->sa_family) {
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 2b82ecc..2d652ad 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -202,7 +202,6 @@ ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
uint32_t *pflags)
{
struct ether_header *eh;
- struct rtentry *rt;
uint32_t lleflags = 0;
int error = 0;
#if defined(INET) || defined(INET6)
@@ -253,8 +252,7 @@ ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
}
if (error == EHOSTDOWN) {
- rt = (ro != NULL) ? ro->ro_rt : NULL;
- if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0)
+ if (ro != NULL && (ro->ro_flags & RT_HAS_GW) != 0)
error = EHOSTUNREACH;
}
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 81b65a63..84ee669 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -119,9 +119,8 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
getmicrotime(&ifp->if_lastchange);
#if defined(INET) || defined(INET6)
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
switch (dst->sa_family) {
diff --git a/sys/net/if_fwsubr.c b/sys/net/if_fwsubr.c
index 626b1cb..a070f61 100644
--- a/sys/net/if_fwsubr.c
+++ b/sys/net/if_fwsubr.c
@@ -106,9 +106,8 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
}
#if defined(INET) || defined(INET6)
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
/*
* For unicast, we make a tag to store the lladdr of the
@@ -145,10 +144,6 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
* doesn't fit into the arp model.
*/
if (unicast) {
- is_gw = 0;
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
error = arpresolve(ifp, is_gw, m, dst, (u_char *) destfw, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c
index 7192998..466784f 100644
--- a/sys/net/if_iso88025subr.c
+++ b/sys/net/if_iso88025subr.c
@@ -214,12 +214,8 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct rtentry *rt0 = NULL;
int is_gw = 0;
- if (ro != NULL) {
- rt0 = ro->ro_rt;
- if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
- }
-
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error)
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index f4ac8b4..1291f7b 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -202,15 +202,12 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro)
{
u_int32_t af;
- struct rtentry *rt = NULL;
#ifdef MAC
int error;
#endif
M_ASSERTPKTHDR(m); /* check if we have the packet header */
- if (ro != NULL)
- rt = ro->ro_rt;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error) {
@@ -219,10 +216,9 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
}
#endif
- if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ if (ro != NULL && ro->ro_flags & (RT_REJECT|RT_BLACKHOLE)) {
m_freem(m);
- return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
- rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ return (ro->ro_flags & RT_BLACKHOLE ? 0 : EHOSTUNREACH);
}
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c
index 82c0add..5657400 100644
--- a/sys/net/radix_mpath.c
+++ b/sys/net/radix_mpath.c
@@ -197,14 +197,49 @@ rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt,
return (0);
}
-void
-rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
+static struct rtentry *
+rt_mpath_selectrte(struct rtentry *rte, uint32_t hash)
{
struct radix_node *rn0, *rn;
u_int32_t n;
struct rtentry *rt;
int64_t weight;
+ /* beyond here, we use rn as the master copy */
+ rn0 = rn = (struct radix_node *)rte;
+ n = rn_mpath_count(rn0);
+
+ /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
+ hash += hashjitter;
+ hash %= n;
+ for (weight = abs((int32_t)hash), rt = rte;
+ weight >= rt->rt_weight && rn;
+ weight -= rt->rt_weight) {
+
+ /* stay within the multipath routes */
+ if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
+ break;
+ rn = rn->rn_dupedkey;
+ rt = (struct rtentry *)rn;
+ }
+
+ return (rt);
+}
+
+struct rtentry *
+rt_mpath_select(struct rtentry *rte, uint32_t hash)
+{
+ if (rn_mpath_next((struct radix_node *)rte) == NULL)
+ return (rte);
+
+ return (rt_mpath_selectrte(rte, hash));
+}
+
+void
+rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
+{
+ struct rtentry *rt;
+
/*
* XXX we don't attempt to lookup cached route again; what should
* be done for sendto(3) case?
@@ -222,34 +257,18 @@ rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
return;
}
- /* beyond here, we use rn as the master copy */
- rn0 = rn = (struct radix_node *)ro->ro_rt;
- n = rn_mpath_count(rn0);
-
- /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
- hash += hashjitter;
- hash %= n;
- for (weight = abs((int32_t)hash), rt = ro->ro_rt;
- weight >= rt->rt_weight && rn;
- weight -= rt->rt_weight) {
-
- /* stay within the multipath routes */
- if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
- break;
- rn = rn->rn_dupedkey;
- rt = (struct rtentry *)rn;
- }
+ rt = rt_mpath_selectrte(ro->ro_rt, hash);
/* XXX try filling rt_gwroute and avoid unreachable gw */
/* gw selection has failed - there must be only zero weight routes */
- if (!rn) {
+ if (!rt) {
RT_UNLOCK(ro->ro_rt);
ro->ro_rt = NULL;
return;
}
if (ro->ro_rt != rt) {
RTFREE_LOCKED(ro->ro_rt);
- ro->ro_rt = (struct rtentry *)rn;
+ ro->ro_rt = rt;
RT_LOCK(ro->ro_rt);
RT_ADDREF(ro->ro_rt);
diff --git a/sys/net/radix_mpath.h b/sys/net/radix_mpath.h
index bcb210e..fc6f777 100644
--- a/sys/net/radix_mpath.h
+++ b/sys/net/radix_mpath.h
@@ -52,6 +52,7 @@ int rt_mpath_conflict(struct radix_node_head *, struct rtentry *,
struct sockaddr *);
void rtalloc_mpath_fib(struct route *, u_int32_t, u_int);
#define rtalloc_mpath(_route, _hash) rtalloc_mpath_fib((_route), (_hash), 0)
+struct rtentry *rt_mpath_select(struct rtentry *, uint32_t);
struct radix_node *rn_mpath_lookup(void *, void *,
struct radix_node_head *);
int rt_mpath_deldup(struct rtentry *, struct rtentry *);
diff --git a/sys/net/route.c b/sys/net/route.c
index e09cc23..9698dd3 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -568,7 +568,7 @@ rtredirect_fib(struct sockaddr *dst,
struct sockaddr *src,
u_int fibnum)
{
- struct rtentry *rt, *rt0 = NULL;
+ struct rtentry *rt;
int error = 0;
short *stat = NULL;
struct rt_addrinfo info;
@@ -627,7 +627,7 @@ rtredirect_fib(struct sockaddr *dst,
* Create new route, rather than smashing route to net.
*/
create:
- rt0 = rt;
+ RTFREE(rt);
rt = NULL;
flags |= RTF_DYNAMIC;
@@ -637,21 +637,14 @@ rtredirect_fib(struct sockaddr *dst,
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_ifa = ifa;
info.rti_flags = flags;
- if (rt0 != NULL)
- RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */
error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
if (rt != NULL) {
RT_LOCK(rt);
- if (rt0 != NULL)
- EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
flags = rt->rt_flags;
}
- if (rt0 != NULL)
- RTFREE(rt0);
stat = &V_rtstat.rts_dynamic;
} else {
- struct rtentry *gwrt;
/*
* Smash the current notion of the gateway to
@@ -669,11 +662,7 @@ rtredirect_fib(struct sockaddr *dst,
RADIX_NODE_HEAD_LOCK(rnh);
RT_LOCK(rt);
rt_setgate(rt, rt_key(rt), gateway);
- gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
RADIX_NODE_HEAD_UNLOCK(rnh);
- EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
- if (gwrt)
- RTFREE_LOCKED(gwrt);
}
} else
error = EHOSTUNREACH;
@@ -858,7 +847,7 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
src = rt_key(rt);
dst = info->rti_info[RTAX_DST];
sa_len = src->sa_len;
- if (src != NULL && dst != NULL) {
+ if (dst != NULL) {
if (src->sa_len > dst->sa_len)
return (ENOMEM);
memcpy(dst, src, src->sa_len);
diff --git a/sys/net/route.h b/sys/net/route.h
index 7c69e1c..f30a72f 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -64,9 +64,13 @@ struct route {
#define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */
#define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */
-#define RT_L2_ME (1 << RT_L2_ME_BIT)
-#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT)
-#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT)
+#define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */
+#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */
+#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */
+
+#define RT_REJECT 0x0020 /* Destination is reject */
+#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */
+#define RT_HAS_GW 0x0080 /* Destination has GW */
struct rt_metrics {
u_long rmx_locks; /* Kernel must leave these values alone */
@@ -215,6 +219,21 @@ fib_rte_to_nh_flags(int rt_flags)
return (res);
}
+#ifdef _KERNEL
+/* rte<>ro_flags translation */
+static inline void
+rt_update_ro_flags(struct route *ro)
+{
+ int rt_flags = ro->ro_rt->rt_flags;
+
+ ro->ro_flags &= ~ (RT_REJECT|RT_BLACKHOLE|RT_HAS_GW);
+
+ ro->ro_flags |= (rt_flags & RTF_REJECT) ? RT_REJECT : 0;
+ ro->ro_flags |= (rt_flags & RTF_BLACKHOLE) ? RT_BLACKHOLE : 0;
+ ro->ro_flags |= (rt_flags & RTF_GATEWAY) ? RT_HAS_GW : 0;
+}
+#endif
+
/*
* Routing statistics.
*/
@@ -467,9 +486,6 @@ int rib_lookup_info(uint32_t, const struct sockaddr *, uint32_t, uint32_t,
struct rt_addrinfo *);
void rib_free_info(struct rt_addrinfo *info);
-#include <sys/eventhandler.h>
-typedef void (*rtevent_redirect_fn)(void *, struct rtentry *, struct rtentry *, struct sockaddr *);
-EVENTHANDLER_DECLARE(route_redirect_event, rtevent_redirect_fn);
#endif
#endif
OpenPOWER on IntegriCloud