Page MenuHomeFreeBSD
Authored By
melifaro
Dec 6 2015, 7:33 PM
Size
8 KB
Referenced Files
None
Subscribers
None

lock_fwd

Index: sys/net/route.c
===================================================================
--- sys/net/route.c (revision 291898)
+++ sys/net/route.c (working copy)
@@ -46,6 +46,8 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
+#include <sys/lock.h>
+#include <sys/rmlock.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/sysproto.h>
@@ -64,6 +66,9 @@
#include <net/radix_mpath.h>
#endif
+#include <net/if_llatbl.h>
+#include <netinet/in_var.h>
+#include <netinet6/in6_var.h>
#include <netinet/in.h>
#include <netinet/ip_mroute.h>
@@ -120,7 +125,9 @@ VNET_DEFINE(struct radix_node_head *, rt_tables);
VNET_DEFINE(int, rttrash); /* routes not in table but not freed */
#define V_rttrash VNET(rttrash)
+struct route groute_storage, *pgroute;
+
/*
* Convert a 'struct radix_node *' to a 'struct rtentry *'.
* The operation can be done safely (in this code) because a
@@ -398,7 +405,54 @@ rtalloc1(struct sockaddr *dst, int report, u_long
return (rtalloc1_fib(dst, report, ignflags, RT_DEFAULT_FIB));
}
+#define _USE_UNLOCKED
+struct rmlock rm_radixlock;
+RM_SYSINIT(rm_radix, &rm_radixlock, "rm_radixlock");
+#ifdef _USE_RM
+#define RADIX_LOCK_READER struct rm_priotracker tracker
+#define RIB_RLOCK(rnh) rm_rlock(&rm_radixlock, &tracker)
+#define RIB_RUNLOCK(rnh) rm_runlock(&rm_radixlock, &tracker)
+#endif
+#ifdef _USE_UNLOCKED
+#define RADIX_LOCK_READER
+#define RIB_RLOCK(rnh)
+#define RIB_RUNLOCK(rnh)
+#else
+#define RADIX_LOCK_READER
+#define RIB_RLOCK(rnh) RADIX_NODE_HEAD_RLOCK(rnh)
+#define RIB_RUNLOCK(rnh) RADIX_NODE_HEAD_RUNLOCK(rnh)
+#endif
+
struct rtentry *
+rtalloc1_fib_nolock(struct sockaddr *dst, int report, u_long ignflags,
+ u_int fibnum)
+{
+ struct radix_node_head *rnh;
+ struct radix_node *rn;
+ struct rtentry *newrt;
+ RADIX_LOCK_READER;
+
+ KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
+ rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
+ newrt = NULL;
+ if (rnh == NULL)
+ return (NULL);
+
+ RIB_RLOCK(rnh);
+
+ rn = rnh->rnh_matchaddr(dst, rnh);
+ if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
+ newrt = RNTORT(rn);
+ RIB_RUNLOCK(rnh);
+ return (newrt);
+
+ }
+
+ RIB_RUNLOCK(rnh);
+ return (NULL);
+}
+
+struct rtentry *
rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
u_int fibnum)
{
@@ -1236,7 +1290,6 @@ rt_updatemtu(struct ifnet *ifp)
}
-#if 0
int p_sockaddr(char *buf, int buflen, struct sockaddr *s);
int rt_print(char *buf, int buflen, struct rtentry *rt);
@@ -1285,8 +1338,56 @@ rt_print(char *buf, int buflen, struct rtentry *rt
return (i);
}
-#endif
+void
+rt_cleargroute(void)
+{
+
+ pgroute = NULL;
+ printf("Clearing global route\n");
+ memset(&groute_storage, 0, sizeof(groute_storage));
+}
+
+void
+rt_setgroute(struct rtentry *rt, struct sockaddr *rdst)
+{
+ char xbuf[128];
+ struct llentry *lle;
+ struct ifnet *ifp;
+
+ memset(xbuf, 0, sizeof(xbuf));
+ rt_print(xbuf, sizeof(xbuf), rt);
+ printf("Selecting route '%s' as default\n", xbuf);
+ groute_storage.ro_rt = rt;
+ if (rt->rt_flags & RTF_GATEWAY)
+ rdst = (struct sockaddr *)rt->rt_gateway;
+
+ p_sockaddr(xbuf, sizeof(xbuf), rdst);
+ lle = NULL;
+ ifp = rt->rt_ifp;
+ switch (rdst->sa_family) {
+ case AF_INET:
+ lle = llentry_alloc(ifp, LLTABLE(ifp), (struct sockaddr_storage *)rdst);
+ if (lle != NULL && (lle->la_flags & LLE_VALID) != 0)
+ printf("Found (valid) lle for %s\n", xbuf);
+ else
+ printf("lle for %s not found or invalid\n", xbuf);
+ break;
+ case AF_INET6:
+ lle = llentry_alloc(ifp, LLTABLE6(ifp), (struct sockaddr_storage *)rdst);
+ if (lle != NULL && (lle->la_flags & LLE_VALID) != 0)
+ printf("Found (valid) lle for %s\n", xbuf);
+ else
+ printf("lle for %s not found or invalid\n", xbuf);
+ break;
+ }
+
+ groute_storage.ro_dst = *rdst;
+ groute_storage.ro_lle = lle;
+ pgroute = &groute_storage;
+}
+
+
#ifdef RADIX_MPATH
/*
* Deletes key for single-path routes, unlinks rtentry with
Index: sys/net/route.h
===================================================================
--- sys/net/route.h (revision 291898)
+++ sys/net/route.h (working copy)
@@ -369,6 +369,13 @@ void rt_maskedcopy(struct sockaddr *, struct soc
int rtsock_addrmsg(int, struct ifaddr *, int);
int rtsock_routemsg(int, struct ifnet *ifp, int, struct rtentry *, int);
+void rt_cleargroute(void);
+void rt_setgroute(struct rtentry *rt, struct sockaddr *dst);
+extern struct route groute_storage, *pgroute;
+struct rtentry *rtalloc1_fib_nolock(struct sockaddr *dst, int report,
+ u_long ignflags, u_int fibnum);
+
+
/*
* Note the following locking behavior:
*
Index: sys/net/rtsock.c
===================================================================
--- sys/net/rtsock.c (revision 291898)
+++ sys/net/rtsock.c (working copy)
@@ -719,6 +719,8 @@ route_output(struct mbuf *m, struct socket *so, ..
if (rt == NULL) {
RADIX_NODE_HEAD_RUNLOCK(rnh);
+ if (info.rti_flags & RTF_PROTO1)
+ rt_cleargroute();
senderr(ESRCH);
}
#ifdef RADIX_MPATH
@@ -775,6 +777,8 @@ route_output(struct mbuf *m, struct socket *so, ..
RT_ADDREF(rt);
RADIX_NODE_HEAD_RUNLOCK(rnh);
+ if (info.rti_flags & RTF_PROTO1)
+ rt_setgroute(rt, info.rti_info[RTAX_DST]);
report:
RT_LOCK_ASSERT(rt);
if ((rt->rt_flags & RTF_HOST) == 0
Index: sys/netinet/if_ether.c
===================================================================
--- sys/netinet/if_ether.c (revision 291898)
+++ sys/netinet/if_ether.c (working copy)
@@ -482,6 +482,24 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int
return (error);
}
+#define _USE_UNLOCKED
+struct rmlock rm_llelock;
+RM_SYSINIT(rm_lle, &rm_llelock, "rm_lldlock");
+#ifdef _USE_RM
+#define LLE_LOCK_READER struct rm_priotracker tracker
+#define _LLTABLE_RLOCK(rnh) rm_rlock(&rm_llelock, &tracker)
+#define _LLTABLE_RUNLOCK(rnh) rm_runlock(&rm_llelock, &tracker)
+#endif
+#ifdef _USE_UNLOCKED
+#define LLE_LOCK_READER
+#define _LLTABLE_RLOCK(ifp)
+#define _LLTABLE_RUNLOCK(ifp)
+#else
+#define LLE_LOCK_READER
+#define _LLTABLE_RLOCK(ifp) IF_AFDATA_RLOCK(ifp)
+#define _LLTABLE_RUNLOCK(ifp) IF_AFDATA_RUNLOCK(ifp)
+#endif
+
/*
* Resolve an IP address into an ethernet address.
* On input:
@@ -502,6 +520,7 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mb
const struct sockaddr *dst, u_char *desten, uint32_t *pflags)
{
struct llentry *la = 0;
+ LLE_LOCK_READER;
if (pflags != NULL)
*pflags = 0;
@@ -520,7 +539,15 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mb
}
}
- IF_AFDATA_RLOCK(ifp);
+#if 0
+ if (pgroute != NULL && pgroute->ro_lle != NULL) {
+ bcopy(&la->ll_addr, desten, ifp->if_addrlen);
+ if (pflags != NULL)
+ *pflags = LLE_VALID | (la->r_flags & RLLE_IFADDR);
+ return (0);
+ }
+#endif
+ _LLTABLE_RLOCK(ifp);
la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, dst);
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
/* Entry found, let's copy lle info */
@@ -533,10 +560,10 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mb
la->r_skip_req = 0; /* Notify that entry was used */
LLE_REQ_UNLOCK(la);
}
- IF_AFDATA_RUNLOCK(ifp);
+ _LLTABLE_RUNLOCK(ifp);
return (0);
}
- IF_AFDATA_RUNLOCK(ifp);
+ _LLTABLE_RUNLOCK(ifp);
return (arpresolve_full(ifp, is_gw, 1, m, dst, desten, pflags));
}
Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c (revision 291898)
+++ sys/netinet/ip_fastfwd.c (working copy)
@@ -114,6 +114,11 @@ ip_findroute(struct route *ro, struct in_addr dest
struct sockaddr_in *dst;
struct rtentry *rt;
+ if (pgroute != NULL) {
+ *ro = *pgroute;
+ return ((struct sockaddr_in *)&ro->ro_dst);
+ }
+
/*
* Find route to destination.
*/
@@ -122,7 +127,7 @@ ip_findroute(struct route *ro, struct in_addr dest
dst->sin_family = AF_INET;
dst->sin_len = sizeof(*dst);
dst->sin_addr.s_addr = dest.s_addr;
- in_rtalloc_ign(ro, 0, M_GETFIB(m));
+ ro->ro_rt = rtalloc1_fib_nolock((struct sockaddr *)dst, 0, 0, M_GETFIB(m));
/*
* Route there and interface still up?
@@ -136,8 +141,8 @@ ip_findroute(struct route *ro, struct in_addr dest
} else {
IPSTAT_INC(ips_noroute);
IPSTAT_INC(ips_cantforward);
- if (rt)
- RTFREE(rt);
+ //if (rt)
+ //RTFREE(rt);
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
return NULL;
}
@@ -353,8 +358,8 @@ forwardlocal:
* Return packet for processing by ip_input().
*/
m->m_flags |= M_FASTFWD_OURS;
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
+ //if (ro.ro_rt)
+ //RTFREE(ro.ro_rt);
return m;
}
/*
@@ -366,7 +371,7 @@ forwardlocal:
m_tag_delete(m, fwd_tag);
m->m_flags &= ~M_IP_NEXTHOP;
}
- RTFREE(ro.ro_rt);
+ //RTFREE(ro.ro_rt);
if ((dst = ip_findroute(&ro, dest, m)) == NULL)
return NULL; /* icmp unreach already sent */
ifp = ro.ro_rt->rt_ifp;
@@ -469,12 +474,12 @@ passout:
IPSTAT_INC(ips_fastforward);
}
consumed:
- RTFREE(ro.ro_rt);
+ //RTFREE(ro.ro_rt);
return NULL;
drop:
if (m)
m_freem(m);
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
+ //if (ro.ro_rt)
+ //RTFREE(ro.ro_rt);
return NULL;
}

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
319315
Default Alt Text
lock_fwd (8 KB)

Event Timeline