summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2007-12-12 20:53:25 +0000
committerkmacy <kmacy@FreeBSD.org>2007-12-12 20:53:25 +0000
commit50706577a436f552d3b0cbb86d7664db6d9231f5 (patch)
treecf3d3c627c21861f7f3ed1f081751dce3c03b24f
parentdcdbd55c9a2abc0ab1398d2734826839ac918c13 (diff)
downloadFreeBSD-src-50706577a436f552d3b0cbb86d7664db6d9231f5.zip
FreeBSD-src-50706577a436f552d3b0cbb86d7664db6d9231f5.tar.gz
add interface for allowing consumers to register for ARP updates,
redirects, and path MTU changes Reviewed by: silby
-rw-r--r--sys/net/route.c17
-rw-r--r--sys/net/route.h7
-rw-r--r--sys/netinet/if_ether.c9
3 files changed, 28 insertions, 5 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 8ea2132..543383a 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -318,7 +318,7 @@ rtredirect(struct sockaddr *dst,
int flags,
struct sockaddr *src)
{
- struct rtentry *rt;
+ struct rtentry *rt, *rt0 = NULL;
int error = 0;
short *stat = NULL;
struct rt_addrinfo info;
@@ -362,8 +362,9 @@ rtredirect(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;
@@ -371,14 +372,19 @@ rtredirect(struct sockaddr *dst,
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_ifa = ifa;
info.rti_flags = flags;
- rt = NULL;
error = rtrequest1(RTM_ADD, &info, &rt);
if (rt != NULL) {
RT_LOCK(rt);
+ EVENTHANDLER_INVOKE(route_event, RTEVENT_REDIRECT_UPDATE, 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!!!
@@ -390,6 +396,9 @@ rtredirect(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_event, RTEVENT_REDIRECT_UPDATE, rt, gwrt, dst);
+ RTFREE_LOCKED(gwrt);
}
} else
error = EHOSTUNREACH;
diff --git a/sys/net/route.h b/sys/net/route.h
index b408213..423cccb 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -359,6 +359,13 @@ int rtrequest(int, struct sockaddr *,
struct sockaddr *, struct sockaddr *, int, struct rtentry **);
int rtrequest1(int, struct rt_addrinfo *, struct rtentry **);
int rt_check(struct rtentry **, struct rtentry **, struct sockaddr *);
+
+#include <sys/eventhandler.h>
+#define RTEVENT_ARP_UPDATE 1
+#define RTEVENT_PMTU_UPDATE 2
+#define RTEVENT_REDIRECT_UPDATE 3
+typedef void (*rtevent_fn)(void *, int, struct rtentry *, struct rtentry *, struct sockaddr *);
+EVENTHANDLER_DECLARE(route_event, rtevent_fn);
#endif
#endif
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 98f26df..33e7704 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -578,7 +578,10 @@ in_arpinput(struct mbuf *m)
#ifdef DEV_CARP
int carp_match = 0;
#endif
-
+ struct sockaddr_in sin;
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = AF_INET;
+
if (ifp->if_bridge)
bridged = 1;
@@ -772,6 +775,10 @@ match:
la->la_preempt = arp_maxtries;
hold = la->la_hold;
la->la_hold = NULL;
+
+ sin.sin_addr.s_addr = ntohl(itaddr.s_addr);
+ EVENTHANDLER_INVOKE(route_event, RTEVENT_ARP_UPDATE, rt, NULL,
+ (struct sockaddr *)&sin);
RT_UNLOCK(rt);
if (hold != NULL)
(*ifp->if_output)(ifp, hold, rt_key(rt), rt);
OpenPOWER on IntegriCloud