summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKip Macy <kmacy@FreeBSD.org>2008-07-31 22:42:27 +0000
committerKip Macy <kmacy@FreeBSD.org>2008-07-31 22:42:27 +0000
commit577ce98540af4540c1707dbdf12abc9f7fbf46ed (patch)
treef6fb52b92f0623614d4aaf1e39679797e8ff4b50
parentfd9e4a89bc8bc156f7b7bd23be9adbc8dd791ac6 (diff)
Notes
-rw-r--r--sys/net/route.c18
-rw-r--r--sys/net/route.h5
-rw-r--r--sys/netinet/if_ether.c31
-rw-r--r--sys/netinet/if_ether.h2
4 files changed, 38 insertions, 18 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 337220ba63e0..27ec37459fcb 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -450,6 +450,7 @@ rtredirect(struct sockaddr *dst,
int flags,
struct sockaddr *src)
{
+
rtredirect_fib(dst, gateway, netmask, flags, src, 0);
}
@@ -461,7 +462,7 @@ rtredirect_fib(struct sockaddr *dst,
struct sockaddr *src,
u_int fibnum)
{
- struct rtentry *rt;
+ struct rtentry *rt, *rt0 = NULL;
int error = 0;
short *stat = NULL;
struct rt_addrinfo info;
@@ -505,8 +506,9 @@ rtredirect_fib(struct sockaddr *dst,
* Create new route, rather than smashing route to net.
*/
create:
- if (rt)
- rtfree(rt);
+ rt0 = rt;
+ rt = NULL;
+
flags |= RTF_GATEWAY | RTF_DYNAMIC;
bzero((caddr_t)&info, sizeof(info));
info.rti_info[RTAX_DST] = dst;
@@ -514,14 +516,19 @@ rtredirect_fib(struct sockaddr *dst,
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_ifa = ifa;
info.rti_flags = flags;
- rt = NULL;
error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
if (rt != NULL) {
RT_LOCK(rt);
+ EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
flags = rt->rt_flags;
}
+ if (rt0)
+ RTFREE_LOCKED(rt0);
+
stat = &rtstat.rts_dynamic;
} else {
+ struct rtentry *gwrt;
+
/*
* Smash the current notion of the gateway to
* this destination. Should check about netmask!!!
@@ -533,6 +540,9 @@ rtredirect_fib(struct sockaddr *dst,
* add the key and gateway (in one malloc'd chunk).
*/
rt_setgate(rt, rt_key(rt), gateway);
+ gwrt = rtalloc1(gateway, 1, 0);
+ EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
+ RTFREE_LOCKED(gwrt);
}
} else
error = EHOSTUNREACH;
diff --git a/sys/net/route.h b/sys/net/route.h
index c3de4e15df54..55bed102d9eb 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -387,6 +387,11 @@ int rtrequest_fib(int, struct sockaddr *,
int rtrequest1_fib(int, struct rt_addrinfo *, struct rtentry **, u_int);
int rt_check_fib(struct rtentry **, struct rtentry **, struct sockaddr *, u_int);
+#include <sys/eventhandler.h>
+typedef void (*rtevent_arp_update_fn)(void *, struct rtentry *, uint8_t *, struct sockaddr *);
+typedef void (*rtevent_redirect_fn)(void *, struct rtentry *, struct rtentry *, struct sockaddr *);
+EVENTHANDLER_DECLARE(route_arp_update_event, rtevent_arp_update_fn);
+EVENTHANDLER_DECLARE(route_redirect_event, rtevent_redirect_fn);
#endif
#endif
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index f84fc933a32c..27365b7af98b 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -364,15 +364,18 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
int error;
int fibnum = 0;
- if (m->m_flags & M_BCAST) { /* broadcast */
- (void)memcpy(desten, ifp->if_broadcastaddr, ifp->if_addrlen);
- return (0);
- }
- if (m->m_flags & M_MCAST && ifp->if_type != IFT_ARCNET) {/* multicast */
- ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
- return (0);
+ if (m) {
+
+ if (m->m_flags & M_BCAST) { /* broadcast */
+ (void)memcpy(desten, ifp->if_broadcastaddr, ifp->if_addrlen);
+ return (0);
+ }
+ if (m->m_flags & M_MCAST && ifp->if_type != IFT_ARCNET) {/* multicast */
+ ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
+ return (0);
+ }
+ fibnum = M_GETFIB(m);
}
- fibnum = M_GETFIB(m);
if (rt0 != NULL) {
/* Look for a cached arp (ll) entry. */
@@ -457,10 +460,12 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
* response yet. Replace the held mbuf with this
* latest one.
*/
- if (la->la_hold)
- m_freem(la->la_hold);
- la->la_hold = m;
-
+ if (m) {
+ if (la->la_hold)
+ m_freem(la->la_hold);
+ la->la_hold = m;
+ }
+
KASSERT(rt->rt_expire > 0, ("sending ARP request for static entry"));
/*
@@ -690,13 +695,11 @@ match:
continue;
sdl = SDL(rt->rt_gateway);
-#if 0 /* -current */ /* Only call this once */
if (firstpass) {
sin.sin_addr.s_addr = isaddr.s_addr;
EVENTHANDLER_INVOKE(route_arp_update_event, rt,
ar_sha(ah), (struct sockaddr *)&sin);
}
-#endif
la = (struct llinfo_arp *)rt->rt_llinfo;
if (la == NULL) {
RT_UNLOCK(rt);
diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h
index 14df15fcc17c..ae2b0d0f9411 100644
--- a/sys/netinet/if_ether.h
+++ b/sys/netinet/if_ether.h
@@ -111,6 +111,8 @@ extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
int arpresolve(struct ifnet *ifp, struct rtentry *rt,
struct mbuf *m, struct sockaddr *dst, u_char *desten);
+int arpresolve2(struct ifnet *ifp, struct rtentry *rt,
+ struct sockaddr *dst, u_char *desten);
void arp_ifinit(struct ifnet *, struct ifaddr *);
void arp_ifinit2(struct ifnet *, struct ifaddr *, u_char *);
#endif