diff options
author | Kip Macy <kmacy@FreeBSD.org> | 2008-07-31 22:42:27 +0000 |
---|---|---|
committer | Kip Macy <kmacy@FreeBSD.org> | 2008-07-31 22:42:27 +0000 |
commit | 577ce98540af4540c1707dbdf12abc9f7fbf46ed (patch) | |
tree | f6fb52b92f0623614d4aaf1e39679797e8ff4b50 | |
parent | fd9e4a89bc8bc156f7b7bd23be9adbc8dd791ac6 (diff) |
Notes
-rw-r--r-- | sys/net/route.c | 18 | ||||
-rw-r--r-- | sys/net/route.h | 5 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 31 | ||||
-rw-r--r-- | sys/netinet/if_ether.h | 2 |
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 |