View | Details | Raw Unified | Return to bug 68692
Collapse All | Expand All

(-)src/sys/net/route.c (-1 / +21 lines)
Lines 42-47 Link Here
42
#include <sys/kernel.h>
42
#include <sys/kernel.h>
43
43
44
#include <net/if.h>
44
#include <net/if.h>
45
#include <net/if_dl.h>		/* for sockaddr_dl */
45
#include <net/route.h>
46
#include <net/route.h>
46
47
47
#include <netinet/in.h>
48
#include <netinet/in.h>
Lines 1105-1113 Link Here
1105
		bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
1106
		bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
1106
}
1107
}
1107
1108
1109
void arp_ifscrub(struct ifnet *ifp, uint32_t addr);
1110
1108
/*
1111
/*
1109
 * Set up a routing table entry, normally
1112
 * Set up a routing table entry, normally
1110
 * for an interface.
1113
 * for an interface.
1114
 * Instead of the destination address, use a sockaddr_dl for the
1115
 * gateway, using the index and type of the interface.
1111
 */
1116
 */
1112
int
1117
int
1113
rtinit(struct ifaddr *ifa, int cmd, int flags)
1118
rtinit(struct ifaddr *ifa, int cmd, int flags)
Lines 1118-1123 Link Here
1118
	struct rtentry *rt = NULL;
1123
	struct rtentry *rt = NULL;
1119
	struct rt_addrinfo info;
1124
	struct rt_addrinfo info;
1120
	int error;
1125
	int error;
1126
	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1121
1127
1122
	if (flags & RTF_HOST) {
1128
	if (flags & RTF_HOST) {
1123
		dst = ifa->ifa_dstaddr;
1129
		dst = ifa->ifa_dstaddr;
Lines 1126-1131 Link Here
1126
		dst = ifa->ifa_addr;
1132
		dst = ifa->ifa_addr;
1127
		netmask = ifa->ifa_netmask;
1133
		netmask = ifa->ifa_netmask;
1128
	}
1134
	}
1135
	printf("rtinit cmd %d flags 0x%x, ifa_ifp %p dst %d:0x%x gw %d:0x%x\n",
1136
	    cmd, flags, ifa->ifa_ifp,
1137
	    dst->sa_family,
1138
	    ntohl(((struct sockaddr_in *)dst)->sin_addr.s_addr),
1139
	    ifa->ifa_addr->sa_family,
1140
	    ntohl(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr));
1141
1129
	/*
1142
	/*
1130
	 * If it's a delete, check that if it exists, it's on the correct
1143
	 * If it's a delete, check that if it exists, it's on the correct
1131
	 * interface or we might scrub a route to another ifa which would
1144
	 * interface or we might scrub a route to another ifa which would
Lines 1136-1141 Link Here
1136
		struct radix_node_head *rnh;
1149
		struct radix_node_head *rnh;
1137
		struct radix_node *rn;
1150
		struct radix_node *rn;
1138
1151
1152
		if (dst->sa_family == AF_INET)
1153
		    arp_ifscrub(ifa->ifa_ifp,
1154
			((struct sockaddr_in *)dst)->sin_addr.s_addr);
1139
		/*
1155
		/*
1140
		 * It's a delete, so it should already exist..
1156
		 * It's a delete, so it should already exist..
1141
		 * If it's a net, mask off the host bits
1157
		 * If it's a net, mask off the host bits
Lines 1175-1184 Link Here
1175
	info.rti_ifa = ifa;
1191
	info.rti_ifa = ifa;
1176
	info.rti_flags = flags | ifa->ifa_flags;
1192
	info.rti_flags = flags | ifa->ifa_flags;
1177
	info.rti_info[RTAX_DST] = dst;
1193
	info.rti_info[RTAX_DST] = dst;
1178
	info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
1194
	info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
1179
	info.rti_info[RTAX_NETMASK] = netmask;
1195
	info.rti_info[RTAX_NETMASK] = netmask;
1180
	error = rtrequest1(cmd, &info, &rt);
1196
	error = rtrequest1(cmd, &info, &rt);
1181
	if (error == 0 && rt != NULL) {
1197
	if (error == 0 && rt != NULL) {
1198
		((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
1199
			rt->rt_ifp->if_type;
1200
		((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
1201
			rt->rt_ifp->if_index;
1182
		/*
1202
		/*
1183
		 * notify any listening routing agents of the change
1203
		 * notify any listening routing agents of the change
1184
		 */
1204
		 */
(-)src/sys/net/rtsock.c (-2 / +28 lines)
Lines 93-98 Link Here
93
			struct rt_metrics *out);
93
			struct rt_metrics *out);
94
static void	rt_dispatch(struct mbuf *, const struct sockaddr *);
94
static void	rt_dispatch(struct mbuf *, const struct sockaddr *);
95
95
96
/* support new arp code */
97
int arp_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info);
98
int sysctl_dumparp(int af, struct sysctl_req *wr);
99
96
/*
100
/*
97
 * It really doesn't make any sense at all for this code to share much
101
 * It really doesn't make any sense at all for this code to share much
98
 * with raw_usrreq.c, since its functionality is so restricted.  XXX
102
 * with raw_usrreq.c, since its functionality is so restricted.  XXX
Lines 277-282 Link Here
277
	sosend, soreceive, sopoll, pru_sosetlabel_null
281
	sosend, soreceive, sopoll, pru_sosetlabel_null
278
};
282
};
279
283
284
285
280
/*ARGSUSED*/
286
/*ARGSUSED*/
281
static int
287
static int
282
route_output(struct mbuf *m, struct socket *so)
288
route_output(struct mbuf *m, struct socket *so)
Lines 353-358 Link Here
353
		if (info.rti_info[RTAX_GATEWAY] == NULL)
359
		if (info.rti_info[RTAX_GATEWAY] == NULL)
354
			senderr(EINVAL);
360
			senderr(EINVAL);
355
		saved_nrt = NULL;
361
		saved_nrt = NULL;
362
		if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) {
363
			/* support for new ARP code */
364
			arp_rt_output(rtm, &info);
365
			break;
366
		}
356
		error = rtrequest1(RTM_ADD, &info, &saved_nrt);
367
		error = rtrequest1(RTM_ADD, &info, &saved_nrt);
357
		if (error == 0 && saved_nrt) {
368
		if (error == 0 && saved_nrt) {
358
			RT_LOCK(saved_nrt);
369
			RT_LOCK(saved_nrt);
Lines 366-371 Link Here
366
377
367
	case RTM_DELETE:
378
	case RTM_DELETE:
368
		saved_nrt = NULL;
379
		saved_nrt = NULL;
380
		if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) {
381
			/* support for new ARP code */
382
			arp_rt_output(rtm, &info);
383
			break;
384
		}
369
		error = rtrequest1(RTM_DELETE, &info, &saved_nrt);
385
		error = rtrequest1(RTM_DELETE, &info, &saved_nrt);
370
		if (error == 0) {
386
		if (error == 0) {
371
			RT_LOCK(saved_nrt);
387
			RT_LOCK(saved_nrt);
Lines 1081-1086 Link Here
1081
	int	i, lim, s, error = EINVAL;
1097
	int	i, lim, s, error = EINVAL;
1082
	u_char	af;
1098
	u_char	af;
1083
	struct	walkarg w;
1099
	struct	walkarg w;
1100
	int found = 0;
1084
1101
1085
	name ++;
1102
	name ++;
1086
	namelen--;
1103
	namelen--;
Lines 1112-1119 Link Here
1112
			    	error = rnh->rnh_walktree(rnh,
1129
			    	error = rnh->rnh_walktree(rnh,
1113
				    sysctl_dumpentry, &w);/* could sleep XXX */
1130
				    sysctl_dumpentry, &w);/* could sleep XXX */
1114
				/* RADIX_NODE_HEAD_UNLOCK(rnh); */
1131
				/* RADIX_NODE_HEAD_UNLOCK(rnh); */
1115
			} else if (af != 0)
1132
				if (error)
1116
				error = EAFNOSUPPORT;
1133
					break;
1134
				found = 1;
1135
			}
1136
		/*
1137
		 * take care of llinfo entries. XXX check AF_INET ?
1138
		 */
1139
		if (w.w_op == NET_RT_FLAGS && (RTF_LLINFO & w.w_arg))
1140
			error = sysctl_dumparp(af, w.w_req);
1141
		else if (af != 0 && found == 0)
1142
			error = EAFNOSUPPORT;
1117
		break;
1143
		break;
1118
1144
1119
	case NET_RT_IFLIST:
1145
	case NET_RT_IFLIST:
(-)src/sys/netinet/if_ether.c (-171 / +466 lines)
Lines 27-33 Link Here
27
 * SUCH DAMAGE.
27
 * SUCH DAMAGE.
28
 *
28
 *
29
 *	@(#)if_ether.c	8.1 (Berkeley) 6/10/93
29
 *	@(#)if_ether.c	8.1 (Berkeley) 6/10/93
30
 * $FreeBSD: src/sys/netinet/if_ether.c,v 1.127 2004/04/25 15:00:17 luigi Exp $
30
 * $FreeBSD$
31
 */
31
 */
32
32
33
/*
33
/*
Lines 101-107 Link Here
101
static	LIST_HEAD(, llinfo_arp) llinfo_arp;
101
static	LIST_HEAD(, llinfo_arp) llinfo_arp;
102
102
103
static struct	ifqueue arpintrq;
103
static struct	ifqueue arpintrq;
104
static int	arp_allocated;
105
104
106
static int	arp_maxtries = 5;
105
static int	arp_maxtries = 5;
107
static int	useloopback = 1; /* use loopback interface for local traffic */
106
static int	useloopback = 1; /* use loopback interface for local traffic */
Lines 116-133 Link Here
116
	   &arp_proxyall, 0, "");
115
	   &arp_proxyall, 0, "");
117
116
118
static void	arp_init(void);
117
static void	arp_init(void);
119
static void	arp_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
120
static void	arprequest(struct ifnet *,
118
static void	arprequest(struct ifnet *,
121
			struct in_addr *, struct in_addr *, u_char *);
119
			struct in_addr *, struct in_addr *, u_char *);
122
static void	arpintr(struct mbuf *);
120
static void	arpintr(struct mbuf *);
123
static void	arptfree(struct llinfo_arp *);
121
static void	arptfree(struct llinfo_arp *);
124
static void	arptimer(void *);
122
static void	arptimer(void *);
125
static struct llinfo_arp
123
struct llentry *arplookup(struct ifnet *ifp, uint32_t addr, uint32_t flags);
126
		*arplookup(u_long, int, int);
127
#ifdef INET
124
#ifdef INET
128
static void	in_arpinput(struct mbuf *);
125
static void	in_arpinput(struct mbuf *);
129
#endif
126
#endif
130
127
128
/***
129
 ***
130
 *** Start of new arp support routines which should go to a separate file.
131
 ***
132
 ***/
133
#define DEB(x)
134
#define	DDB(x)	x
135
136
struct llentry {
137
	struct llentry *lle_next;
138
	struct mbuf	*la_hold;
139
	uint16_t	flags; /* see values in if_ether.h */
140
	uint8_t		la_preempt;
141
	uint8_t		la_asked;
142
	time_t		expire;
143
	struct in_addr	l3_addr;
144
	union {
145
		uint64_t	mac_aligned;
146
		uint16_t	mac16[3];
147
	} ll_addr;
148
};
149
150
MALLOC_DEFINE(M_ARP, "arp", "arp entries");	/* XXX will move to UMA */
151
152
int arp_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info);
153
int sysctl_dumparp(int af, struct sysctl_req *wr);
154
void arp_ifscrub(struct ifnet *ifp, uint32_t addr);
155
156
/*
157
 * called by in_ifscrub to remove entry from the table when
158
 * the interface goes away
159
 */
160
void
161
arp_ifscrub(struct ifnet *ifp, uint32_t addr)
162
{
163
	arplookup(ifp, addr, LLE_DELETE | LLE_IFADDR);
164
}
165
166
/*
167
 * Find an interface address matching the ifp-addr pair.
168
 * This may replicate some of the functions of ifa_ifwithnet()
169
 */
170
static struct ifaddr *
171
find_ifa(struct ifnet *ifp, uint32_t addr)
172
{
173
	struct ifaddr *ifa;
174
175
	if (ifp == NULL)
176
		return NULL;
177
	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
178
		if (ifa->ifa_addr->sa_family != AF_INET)
179
			continue;
180
		if (ifp->if_flags & IFF_POINTOPOINT)
181
			break;
182
		if (((addr ^ SIN(ifa->ifa_addr)->sin_addr.s_addr) &
183
		    SIN(ifa->ifa_netmask)->sin_addr.s_addr ) == 0)
184
			break; /* found! */
185
	}
186
	return ifa;
187
}
188
189
static void
190
llentry_free(struct llentry **e)
191
{
192
	struct llentry *x;
193
194
	if (e == 0)
195
		panic("llentry_free: null ptr");
196
	x = *e;
197
	*e = x->lle_next;
198
	if (x->la_hold)
199
		m_freem(x->la_hold);
200
	free(x, M_ARP);
201
}
202
203
/*
204
 * Add a new table at the head of the list for interface ifp
205
 */
206
struct lltable *
207
lltable_new(struct ifnet *ifp, int af)
208
{
209
	struct lltable *t;
210
211
	t = malloc(sizeof (struct lltable), M_ARP, M_DONTWAIT | M_ZERO);
212
	if (t != NULL) {
213
		t->llt_next = ifp->lltables;
214
		t->llt_af = af;
215
		ifp->lltables = t;
216
	}
217
	return t;
218
}
219
220
struct lltable **
221
lltable_free(struct lltable **t)
222
{
223
	struct lltable *x;
224
225
	if (t == NULL)
226
		panic("lltable_free: null ptr");
227
	x = *t;
228
	*t = x->llt_next;
229
	free(x, M_ARP);
230
	return t;
231
}
232
233
static void
234
newarptimer(__unused void *ignored_arg)
235
{
236
	struct lltable *t;
237
	struct llentry **e;
238
	struct ifnet *ifp;
239
240
	IFNET_RLOCK();
241
	printf("arptimer!\n");
242
	TAILQ_FOREACH(ifp, &ifnet, if_link) {
243
		for (t = ifp->lltables; t ; t = t->llt_next) {
244
			if (t->llt_af != AF_INET)
245
				continue;
246
			for (e = (struct llentry **)&t->lle_head; *e; ) {
247
				int kill;
248
249
				if ((*e)->flags & LLE_DELETED)
250
					kill = 1;
251
				else if ((*e)->flags & LLE_STATIC)
252
					kill = 0;
253
				else
254
					kill = time_second >= (*e)->expire;
255
				if (kill)
256
					llentry_free(e);
257
				else
258
					e = &((*e)->lle_next);
259
			}
260
		}
261
	}
262
	IFNET_RUNLOCK();
263
	callout_reset(&arp_callout, arpt_prune * hz, newarptimer, NULL);
264
}
265
266
static int
267
inet_dumparp(struct ifnet *ifp, void *head, struct sysctl_req *wr)
268
{
269
	struct llentry *e;
270
	int error = 0;
271
272
	for (e = head; e; e = e->lle_next) {
273
		struct {
274
			struct rt_msghdr        rtm;
275
			struct sockaddr_inarp   sin2;
276
			struct sockaddr_dl      sdl;
277
			//struct sockaddr_inarp addr2;
278
		} d;
279
280
		DEB(printf("ifp %p index %d flags 0x%x ip %x %s\n",
281
		    ifp, ifp->if_index,
282
		    e->flags,
283
		    ntohl(e->l3_addr.s_addr),
284
		    (e->flags & LLA_VALID) ? "valid" : "incomplete");)
285
		if (e->flags & LLE_DELETED) /* skip deleted entries */
286
			continue;
287
		/*
288
		 * produce a msg made of:
289
		 *  struct rt_msghdr;
290
		 *  struct sockaddr_inarp;
291
		 *  struct sockaddr_dl;
292
		 */
293
		bzero(&d, sizeof (d));
294
		d.rtm.rtm_msglen = sizeof(d);
295
		d.sin2.sin_family = AF_INET;
296
		d.sin2.sin_len = sizeof(d.sin2);
297
		d.sin2.sin_addr.s_addr = e->l3_addr.s_addr;
298
299
		if (e->flags & LLA_VALID) { /* valid MAC */
300
			d.sdl.sdl_family = AF_LINK;
301
			d.sdl.sdl_len = sizeof(d.sdl);
302
			d.sdl.sdl_alen = ifp->if_addrlen;
303
			d.sdl.sdl_index = ifp->if_index;
304
			d.sdl.sdl_type = ifp->if_type;
305
			bcopy(&e->ll_addr, LLADDR(&d.sdl), ifp->if_addrlen);
306
		}
307
		d.rtm.rtm_rmx.rmx_expire =
308
		    e->flags & LLE_STATIC ? 0 : e->expire;
309
		d.rtm.rtm_flags = RTF_LLINFO;
310
		if (e->flags & LLE_STATIC)
311
			d.rtm.rtm_flags |= RTF_STATIC;
312
		d.rtm.rtm_index = ifp->if_index;
313
		error = SYSCTL_OUT(wr, &d, sizeof(d));
314
		if (error)
315
			break;
316
	}
317
	return error;
318
}
319
320
/*
321
 * glue to dump arp tables
322
 */
323
int
324
sysctl_dumparp(int af, struct sysctl_req *wr)
325
{
326
	struct lltable *t;
327
	struct ifnet *ifp;
328
	int error = 0;
329
330
	IFNET_RLOCK();
331
	TAILQ_FOREACH(ifp, &ifnet, if_link) {
332
		for (t = ifp->lltables; t ; t = t->llt_next) {
333
			if (af != 0 && t->llt_af != af)
334
				continue;
335
			switch (af) {
336
			case AF_INET:
337
				error = inet_dumparp(ifp, t->lle_head, wr);
338
				break;
339
			/* other handlers, if any */
340
			}
341
			if (error)
342
				goto done;
343
		}
344
	 }
345
done:
346
	IFNET_RUNLOCK();
347
	return (error);
348
}
349
350
/*
351
 * Called in route_output when adding/deleting a route to an interface.
352
 */
353
int
354
arp_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
355
{
356
	struct sockaddr_dl *dl =
357
		(struct sockaddr_dl *)info->rti_info[RTAX_GATEWAY];
358
	struct sockaddr_in *dst =
359
		(struct sockaddr_in *)info->rti_info[RTAX_DST];
360
	struct ifnet *ifp;
361
	struct llentry *la;
362
	u_int flags;
363
364
	printf("arp_rt_output type %d af: gw %d dst %d:%x if_index %d\n",
365
	    rtm->rtm_type,
366
	    dl ? dl->sdl_family : 0,
367
	    dst ? dst->sin_family : 0,
368
	    dst && dst->sin_family == AF_INET ?
369
	    ntohl(dst->sin_addr.s_addr) : 0,
370
	    dl ? dl->sdl_index : 0);
371
	if (dl == NULL || dl->sdl_family != AF_LINK) {
372
		/* XXX should also check (dl->sdl_index < if_indexlim) */
373
		printf("invalid gateway/index\n");
374
		return EINVAL;
375
	}
376
	ifp = ifnet_byindex(dl->sdl_index);
377
	if (ifp == NULL) {
378
		printf("invalid ifp\n");
379
		return EINVAL;
380
	}
381
382
	switch (rtm->rtm_type) {
383
	case RTM_ADD:
384
		flags = LLE_CREATE;
385
		break;
386
387
	case RTM_CHANGE:
388
	default:
389
		return EINVAL; /* XXX not implemented yet */
390
391
	case RTM_DELETE:
392
		flags = LLE_DELETE;
393
		break;
394
	}
395
	la = arplookup(ifp, dst->sin_addr.s_addr, flags);
396
	if (la == NULL) {
397
		bcopy(LLADDR(dl), &la->ll_addr, ifp->if_addrlen);
398
		la->flags |= LLA_VALID;
399
		if (rtm->rtm_flags & RTF_STATIC)
400
			la->flags |= LLE_STATIC;
401
		else
402
			la->expire = time_second + arpt_keep;
403
	}
404
	return 0;
405
}
406
407
408
409
/***
410
 ***
411
 *** End of new arp support routines which should go to a separate file.
412
 ***
413
 ***/
414
131
/*
415
/*
132
 * Timeout routine.  Age arp_tab entries periodically.
416
 * Timeout routine.  Age arp_tab entries periodically.
133
 */
417
 */
Lines 152-157 Link Here
152
	callout_reset(&arp_callout, arpt_prune * hz, arptimer, NULL);
436
	callout_reset(&arp_callout, arpt_prune * hz, arptimer, NULL);
153
}
437
}
154
438
439
#if 0 /* this is unused */
440
static int	arp_allocated;
441
155
/*
442
/*
156
 * Parallel to llc_rtrequest.
443
 * Parallel to llc_rtrequest.
157
 */
444
 */
Lines 284-289 Link Here
284
		Free((caddr_t)la);
571
		Free((caddr_t)la);
285
	}
572
	}
286
}
573
}
574
#endif /* arp_rtrequest unused */
287
575
288
/*
576
/*
289
 * Broadcast an ARP request. Caller specifies:
577
 * Broadcast an ARP request. Caller specifies:
Lines 301-306 Link Here
301
	struct arphdr *ah;
589
	struct arphdr *ah;
302
	struct sockaddr sa;
590
	struct sockaddr sa;
303
591
592
	if (sip == NULL) {
593
		/*
594
		 * The caller did not supply a source address, try to find
595
		 * a compatible one among those assigned to this interface.
596
		 */
597
		struct ifaddr *ifa;
598
599
		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
600
			if (!ifa->ifa_addr ||
601
			    ifa->ifa_addr->sa_family != AF_INET)
602
				continue;
603
			sip = &SIN(ifa->ifa_addr)->sin_addr;
604
			if (0 == ((sip->s_addr ^ tip->s_addr) &
605
			    SIN(ifa->ifa_netmask)->sin_addr.s_addr) )
606
				break;	/* found it. */
607
		}
608
	}
609
	if (sip == NULL) {
610
		printf(" cannot find matching address, no arprequest\n");
611
		return;
612
	}
613
304
	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
614
	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
305
		return;
615
		return;
306
	m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
616
	m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
Lines 344-359 Link Here
344
arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
654
arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
345
	struct sockaddr *dst, u_char *desten)
655
	struct sockaddr *dst, u_char *desten)
346
{
656
{
347
	struct llinfo_arp *la = 0;
657
	struct llentry *la = 0;
348
	struct sockaddr_dl *sdl;
658
	struct sockaddr_dl *sdl;
349
	int error;
350
	struct rtentry *rt;
659
	struct rtentry *rt;
351
660
	u_int flags = (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) ?
352
	error = rt_check(&rt, &rt0, dst);
661
			0 : LLE_CREATE;
353
	if (error) {
354
		m_freem(m);
355
		return error;
356
	}
357
662
358
	if (m->m_flags & M_BCAST) {	/* broadcast */
663
	if (m->m_flags & M_BCAST) {	/* broadcast */
359
		(void)memcpy(desten, ifp->if_broadcastaddr, ifp->if_addrlen);
664
		(void)memcpy(desten, ifp->if_broadcastaddr, ifp->if_addrlen);
Lines 363-413 Link Here
363
		ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
668
		ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
364
		return (0);
669
		return (0);
365
	}
670
	}
366
	if (rt)
671
	la = arplookup(ifp, SIN(dst)->sin_addr.s_addr, flags);
367
		la = (struct llinfo_arp *)rt->rt_llinfo;
672
	if (la == NULL) {
368
	if (la == 0) {
673
	        if (flags & LLE_CREATE)
369
		la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0);
674
		        log(LOG_DEBUG,
370
		if (la)
675
				"arpresolve: can't allocate llinfo for %s\n",
371
			rt = la->la_rt;
676
				inet_ntoa(SIN(dst)->sin_addr));
372
	}
373
	if (la == 0 || rt == 0) {
374
		log(LOG_DEBUG, "arpresolve: can't allocate llinfo for %s%s%s\n",
375
			inet_ntoa(SIN(dst)->sin_addr), la ? "la" : "",
376
				rt ? "rt" : "");
377
		m_freem(m);
677
		m_freem(m);
378
		return (EINVAL); /* XXX */
678
		return (EINVAL); /* XXX */
379
	}
679
	}
380
	sdl = SDL(rt->rt_gateway);
680
	sdl = SDL(rt->rt_gateway);
381
	/*
681
	/*
382
	 * Check the address family and length is valid, the address
682
	 * If the entry is valid and not expired, use it.
383
	 * is resolved; otherwise, try to resolve.
384
	 */
683
	 */
385
	if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
684
	if (la->flags & LLA_VALID &&
386
	    sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
685
	    (la->flags & LLE_STATIC || la->expire > time_second)) {
686
	        bcopy(&la->ll_addr, desten, ifp->if_addrlen);
387
		/*
687
		/*
388
		 * If entry has an expiry time and it is approaching,
688
		 * If entry has an expiry time and it is approaching,
389
		 * see if we need to send an ARP request within this
689
		 * see if we need to send an ARP request within this
390
		 * arpt_down interval.
690
		 * arpt_down interval.
391
		 */
691
		 */
392
		if ((rt->rt_expire != 0) &&
692
		if (!(la->flags & LLE_STATIC) &&
393
		    (time_second + la->la_preempt > rt->rt_expire)) {
693
		    time_second + la->la_preempt > la->expire) {
394
			arprequest(ifp,
694
		        arprequest(ifp, NULL,
395
				   &SIN(rt->rt_ifa->ifa_addr)->sin_addr,
695
				&SIN(dst)->sin_addr, IF_LLADDR(ifp));
396
				   &SIN(dst)->sin_addr,
397
				   IF_LLADDR(ifp));
398
			la->la_preempt--;
696
			la->la_preempt--;
399
		} 
697
		} 
400
698
401
		bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
402
		return (0);
699
		return (0);
403
	}
700
	}
404
	/*
701
	if (la->flags & LLE_STATIC) {   /* should not happen! */
405
	 * If ARP is disabled or static on this interface, stop.
702
	        log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n",
406
	 * XXX
703
				inet_ntoa(SIN(dst)->sin_addr));
407
	 * Probably should not allocate empty llinfo struct if we are
408
	 * not going to be sending out an arp request.
409
	 */
410
	if (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) {
411
		m_freem(m);
704
		m_freem(m);
412
		return (EINVAL);
705
		return (EINVAL);
413
	}
706
	}
Lines 419-444 Link Here
419
	if (la->la_hold)
712
	if (la->la_hold)
420
		m_freem(la->la_hold);
713
		m_freem(la->la_hold);
421
	la->la_hold = m;
714
	la->la_hold = m;
422
	if (rt->rt_expire) {
715
	/*
423
		RT_LOCK(rt);
716
	 * Now implement the logic to issue requests -- we can send up
424
		rt->rt_flags &= ~RTF_REJECT;
717
	 * to arp_maxtries with a 1-sec spacing, followed by a pause
425
		if (la->la_asked == 0 || rt->rt_expire != time_second) {
718
	 * of arpt_down seconds if no replies are coming back.
426
			rt->rt_expire = time_second;
719
	 * Take the chance to enforce limits on arp_maxtries and arpt_down
427
			if (la->la_asked++ < arp_maxtries) {
720
	 */
428
				arprequest(ifp,
721
	if (la->expire <= time_second) { /* ok, expired */
429
					   &SIN(rt->rt_ifa->ifa_addr)->sin_addr,
722
		if (arp_maxtries > 100) /* enforce a sane limit */
430
					   &SIN(dst)->sin_addr,
723
			arp_maxtries = 100;
431
					   IF_LLADDR(ifp));
724
		else if (arp_maxtries < 3)
432
			} else {
725
			arp_maxtries = 3;
433
				rt->rt_flags |= RTF_REJECT;
726
		if (la->la_asked++ < arp_maxtries)
434
				rt->rt_expire += arpt_down;
727
			la->expire = time_second + 1;
435
				la->la_asked = 0;
728
		else {
436
				la->la_preempt = arp_maxtries;
729
			la->la_asked = 0;
437
			}
730
			la->expire = time_second + arpt_down;
438
731
			la->la_preempt = arp_maxtries;
439
		}
732
		}
440
		RT_UNLOCK(rt);
733
		arprequest(ifp, NULL, &SIN(dst)->sin_addr, IF_LLADDR(ifp));
441
	}
734
        }
442
	return (EWOULDBLOCK);
735
	return (EWOULDBLOCK);
443
}
736
}
444
737
Lines 518-533 Link Here
518
{
811
{
519
	struct arphdr *ah;
812
	struct arphdr *ah;
520
	struct ifnet *ifp = m->m_pkthdr.rcvif;
813
	struct ifnet *ifp = m->m_pkthdr.rcvif;
521
	struct iso88025_header *th = (struct iso88025_header *)0;
814
	struct llentry *la = 0;
522
	struct iso88025_sockaddr_dl_data *trld;
523
	struct llinfo_arp *la = 0;
524
	struct rtentry *rt;
525
	struct ifaddr *ifa;
815
	struct ifaddr *ifa;
526
	struct in_ifaddr *ia;
816
	struct in_ifaddr *ia;
527
	struct sockaddr_dl *sdl;
528
	struct sockaddr sa;
817
	struct sockaddr sa;
529
	struct in_addr isaddr, itaddr, myaddr;
818
	struct in_addr isaddr, itaddr, myaddr;
530
	int op, rif_len;
819
	int op;
531
	int req_len;
820
	int req_len;
532
821
533
	req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
822
	req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));
Lines 540-545 Link Here
540
	op = ntohs(ah->ar_op);
829
	op = ntohs(ah->ar_op);
541
	(void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
830
	(void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
542
	(void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
831
	(void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
832
	/*
833
	 * sanity check for the address length.
834
	 * XXX this does not work for protocols with variable address
835
	 * length. -is
836
	 */
837
	if (ifp->if_addrlen != ah->ar_hln) {
838
		log(LOG_WARNING,
839
		    "arp from %*D: addr len: new %d, i/f %d (ignored)",
840
		    ifp->if_addrlen, (u_char *) ar_sha(ah), ":",
841
		    ah->ar_hln, ifp->if_addrlen);
842
		goto drop;
843
	}
844
543
#ifdef BRIDGE
845
#ifdef BRIDGE
544
#define BRIDGE_TEST (do_bridge)
846
#define BRIDGE_TEST (do_bridge)
545
#else
847
#else
Lines 592-653 Link Here
592
	}
894
	}
593
	if (ifp->if_flags & IFF_STATICARP)
895
	if (ifp->if_flags & IFF_STATICARP)
594
		goto reply;
896
		goto reply;
595
	la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
897
	/* Look up the source. If I am the target, create an entry for it. */
596
	if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
898
	la = arplookup(ifp, isaddr.s_addr,
597
		/* the following is not an error when doing bridging */
899
	    (itaddr.s_addr == myaddr.s_addr) ? LLE_CREATE : 0);
598
		if (!BRIDGE_TEST && rt->rt_ifp != ifp) {
900
	if (la != NULL) {
599
			if (log_arp_wrong_iface)
901
		/* We have a valid entry. Check and store the MAC. */
600
				log(LOG_ERR, "arp: %s is on %s but got reply from %*D on %s\n",
902
		if (la->flags & LLA_VALID &&
601
				    inet_ntoa(isaddr),
903
		    bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
602
				    rt->rt_ifp->if_xname,
904
			if (la->flags & LLE_STATIC) {
603
				    ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
604
				    ifp->if_xname);
605
			goto reply;
606
		}
607
		if (sdl->sdl_alen &&
608
		    bcmp(ar_sha(ah), LLADDR(sdl), sdl->sdl_alen)) {
609
			if (rt->rt_expire) {
610
			    if (log_arp_movements)
611
			        log(LOG_INFO, "arp: %s moved from %*D to %*D on %s\n",
612
				    inet_ntoa(isaddr),
613
				    ifp->if_addrlen, (u_char *)LLADDR(sdl), ":",
614
				    ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
615
				    ifp->if_xname);
616
			} else {
617
			    log(LOG_ERR,
905
			    log(LOG_ERR,
618
				"arp: %*D attempts to modify permanent entry for %s on %s\n",
906
				"arp: %*D attempts to modify permanent entry for %s on %s\n",
619
				ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
907
				ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
620
				inet_ntoa(isaddr), ifp->if_xname);
908
				inet_ntoa(isaddr), ifp->if_xname);
621
			    goto reply;
909
			    goto reply;
622
			}
910
			}
911
			if (log_arp_movements)
912
			        log(LOG_INFO, "arp: %s moved from %*D to %*D on %s\n",
913
				    inet_ntoa(isaddr),
914
				    ifp->if_addrlen, (u_char *)&la->ll_addr, ":",
915
				    ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
916
				    ifp->if_xname);
623
		}
917
		}
624
		/*
918
		bcopy(ar_sha(ah), &la->ll_addr, ifp->if_addrlen);
625
		 * sanity check for the address length.
919
		la->flags |= LLA_VALID;
626
		 * XXX this does not work for protocols with variable address
920
#if 0 /* XXX this needs to be fixed */
627
		 * length. -is
628
		 */
629
		if (sdl->sdl_alen &&
630
		    sdl->sdl_alen != ah->ar_hln) {
631
			log(LOG_WARNING,
632
			    "arp from %*D: new addr len %d, was %d",
633
			    ifp->if_addrlen, (u_char *) ar_sha(ah), ":",
634
			    ah->ar_hln, sdl->sdl_alen);
635
		}
636
		if (ifp->if_addrlen != ah->ar_hln) {
637
			log(LOG_WARNING,
638
			    "arp from %*D: addr len: new %d, i/f %d (ignored)",
639
			    ifp->if_addrlen, (u_char *) ar_sha(ah), ":",
640
			    ah->ar_hln, ifp->if_addrlen);
641
			goto reply;
642
		}
643
		(void)memcpy(LLADDR(sdl), ar_sha(ah),
644
		    sdl->sdl_alen = ah->ar_hln);
645
		/*
921
		/*
646
		 * If we receive an arp from a token-ring station over
922
		 * If we receive an arp from a token-ring station over
647
		 * a token-ring nic then try to save the source
923
		 * a token-ring nic then try to save the source
648
		 * routing info.
924
		 * routing info.
649
		 */
925
		 */
650
		if (ifp->if_type == IFT_ISO88025) {
926
		if (ifp->if_type == IFT_ISO88025) {
927
			struct iso88025_header *th;
928
			struct iso88025_sockaddr_dl_data *trld;
929
			struct sockaddr_dl *sdl;
930
			int rif_len;
931
651
			th = (struct iso88025_header *)m->m_pkthdr.header;
932
			th = (struct iso88025_header *)m->m_pkthdr.header;
652
			trld = SDL_ISO88025(sdl);
933
			trld = SDL_ISO88025(sdl);
653
			rif_len = TR_RCF_RIFLEN(th->rcf);
934
			rif_len = TR_RCF_RIFLEN(th->rcf);
Lines 673-687 Link Here
673
			m->m_pkthdr.len += 8;
954
			m->m_pkthdr.len += 8;
674
			th->rcf = trld->trld_rcf;
955
			th->rcf = trld->trld_rcf;
675
		}
956
		}
676
		RT_LOCK(rt);
957
#endif
677
		if (rt->rt_expire)
958
		if (!(la->flags & LLE_STATIC))
678
			rt->rt_expire = time_second + arpt_keep;
959
			la->expire = time_second + arpt_keep;
679
		rt->rt_flags &= ~RTF_REJECT;
680
		RT_UNLOCK(rt);
681
		la->la_asked = 0;
960
		la->la_asked = 0;
682
		la->la_preempt = arp_maxtries;
961
		la->la_preempt = arp_maxtries;
683
		if (la->la_hold) {
962
		if (la->la_hold) {
684
			(*ifp->if_output)(ifp, la->la_hold, rt_key(rt), rt);
963
			struct sockaddr_in sin;
964
965
			bzero(&sin, sizeof(sin));
966
			sin.sin_len = sizeof(struct sockaddr_in);
967
			sin.sin_family = AF_INET;
968
			sin.sin_addr.s_addr = la->l3_addr.s_addr;
969
			ifp->if_output(ifp, la->la_hold,
970
				(struct sockaddr *)&sin, NULL);
685
			la->la_hold = 0;
971
			la->la_hold = 0;
686
		}
972
		}
687
	}
973
	}
Lines 693-701 Link Here
693
		(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
979
		(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
694
		(void)memcpy(ar_sha(ah), IF_LLADDR(ifp), ah->ar_hln);
980
		(void)memcpy(ar_sha(ah), IF_LLADDR(ifp), ah->ar_hln);
695
	} else {
981
	} else {
696
		la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
982
		la = arplookup(ifp, itaddr.s_addr, LLE_PROXY);
697
		if (la == NULL) {
983
		if (la == NULL) {
698
			struct sockaddr_in sin;
984
			struct sockaddr_in sin;
985
			struct rtentry *rt;
699
986
700
			if (!arp_proxyall)
987
			if (!arp_proxyall)
701
				goto drop;
988
				goto drop;
Lines 747-756 Link Here
747
			       inet_ntoa(itaddr));
1034
			       inet_ntoa(itaddr));
748
#endif
1035
#endif
749
		} else {
1036
		} else {
750
			rt = la->la_rt;
751
			(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
1037
			(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
752
			sdl = SDL(rt->rt_gateway);
1038
			(void)memcpy(ar_sha(ah),  &la->ll_addr, ah->ar_hln);
753
			(void)memcpy(ar_sha(ah), LLADDR(sdl), ah->ar_hln);
754
		}
1039
		}
755
	}
1040
	}
756
1041
Lines 798-863 Link Here
798
/*
1083
/*
799
 * Lookup or enter a new address in arptab.
1084
 * Lookup or enter a new address in arptab.
800
 */
1085
 */
801
static struct llinfo_arp *
1086
struct llentry *
802
arplookup(addr, create, proxy)
1087
arplookup(struct ifnet *ifp, uint32_t l3addr, u_int flags)
803
	u_long addr;
804
	int create, proxy;
805
{
1088
{
806
	struct rtentry *rt;
1089
	struct llentry *e;
807
	struct sockaddr_inarp sin;
1090
	struct lltable *t;
808
	const char *why = 0;
1091
	// uint proxy = flags & LLE_PROXY;
809
1092
810
	bzero(&sin, sizeof(sin));
1093
	if (ifp == NULL)
811
	sin.sin_len = sizeof(sin);
1094
		return NULL;
812
	sin.sin_family = AF_INET;
1095
	/* LOCK_IFNET */
813
	sin.sin_addr.s_addr = addr;
1096
	for (t = ifp->lltables; t && t->llt_af != AF_INET; t = t->llt_next)
814
	if (proxy)
1097
		;
815
		sin.sin_other = SIN_PROXY;
1098
	if (t == NULL && flags & LLE_CREATE)
816
	rt = rtalloc1((struct sockaddr *)&sin, create, 0UL);
1099
		t = lltable_new(ifp, AF_INET);
817
	if (rt == 0)
1100
	if (t == NULL) {
818
		return (0);
1101
		/* UNLOCK_ALL_TABLES */
819
1102
		return NULL;    /* failed! */
820
	if (rt->rt_flags & RTF_GATEWAY)
1103
	}
821
		why = "host is not on local network";
1104
	/* LOCK_TABLE(t) */
822
	else if ((rt->rt_flags & RTF_LLINFO) == 0)
1105
	/* UNLOCK_ALL_TABLES */
823
		why = "could not allocate llinfo";
1106
	for (e = (struct llentry *)t->lle_head; e ; e = e->lle_next) {
824
	else if (rt->rt_gateway->sa_family != AF_LINK)
1107
		if (e->flags & LLE_DELETED)
825
		why = "gateway route is not ours";
1108
			continue;
826
1109
		if (l3addr == e->l3_addr.s_addr)
827
	if (why) {
1110
			break;
828
#define	ISDYNCLONE(_rt) \
1111
        }
829
	(((_rt)->rt_flags & (RTF_STATIC | RTF_WASCLONED)) == RTF_WASCLONED)
1112
	if (e == NULL) {        /* entry not found */
830
		if (create)
1113
		if (!(flags & LLE_CREATE))
831
			log(LOG_DEBUG, "arplookup %s failed: %s\n",
1114
			goto done;
832
			    inet_ntoa(sin.sin_addr), why);
1115
		if (find_ifa(ifp, l3addr) == NULL) {
833
		/*
1116
			printf("host is not on local network\n");
834
		 * If there are no references to this Layer 2 route,
1117
			goto done;
835
		 * and it is a cloned route, and not static, and
1118
		}
836
		 * arplookup() is creating the route, then purge
1119
		e = malloc(sizeof (struct llentry), M_ARP, M_DONTWAIT | M_ZERO);
837
		 * it from the routing table as it is probably bogus.
1120
		if (e == NULL) {
838
		 */
1121
			printf("arp malloc failed\n");
839
		if (rt->rt_refcnt == 1 && ISDYNCLONE(rt))
1122
			goto done;
840
			rtexpunge(rt);
1123
		}
841
		RTFREE_LOCKED(rt);
1124
		e->expire = time_second; /* mark expired */
842
		return (0);
1125
		e->l3_addr.s_addr = l3addr;
843
#undef ISDYNCLONE
1126
		e->lle_next = t->lle_head;
844
	} else {
1127
		t->lle_head = e;
845
		RT_REMREF(rt);
1128
	}
846
		RT_UNLOCK(rt);
1129
	if (flags & LLE_DELETE &&
847
		return ((struct llinfo_arp *)rt->rt_llinfo);
1130
	    (e->flags & LLE_IFADDR) == (flags & LLE_IFADDR))
848
	}
1131
		e->flags = LLE_DELETED;
1132
done:
1133
	/* UNLOCK(t) */
1134
	return e;
849
}
1135
}
850
1136
1137
851
void
1138
void
852
arp_ifinit(ifp, ifa)
1139
arp_ifinit(ifp, ifa)
853
	struct ifnet *ifp;
1140
	struct ifnet *ifp;
854
	struct ifaddr *ifa;
1141
	struct ifaddr *ifa;
855
{
1142
{
1143
	struct llentry *la;
1144
1145
	printf("arp_ifinit ifp %p addr 0x%x\n",
1146
	    ifp, ntohl(IA_SIN(ifa)->sin_addr.s_addr));
1147
856
	if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
1148
	if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
857
		arprequest(ifp, &IA_SIN(ifa)->sin_addr,
1149
		arprequest(ifp, &IA_SIN(ifa)->sin_addr,
858
				&IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp));
1150
				&IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp));
859
	ifa->ifa_rtrequest = arp_rtrequest;
1151
	la = arplookup(ifp, IA_SIN(ifa)->sin_addr.s_addr, LLE_CREATE);
860
	ifa->ifa_flags |= RTF_CLONING;
1152
	if (la) {	/* store our address */
1153
		bcopy(IF_LLADDR(ifp), &la->ll_addr, ifp->if_addrlen);
1154
		la->flags |= LLA_VALID | LLE_STATIC | LLE_IFADDR;
1155
	}
1156
	ifa->ifa_rtrequest = NULL;
861
}
1157
}
862
1158
863
static void
1159
static void
Lines 866-874 Link Here
866
1162
867
	arpintrq.ifq_maxlen = 50;
1163
	arpintrq.ifq_maxlen = 50;
868
	mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF);
1164
	mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF);
869
	LIST_INIT(&llinfo_arp);
870
	callout_init(&arp_callout, CALLOUT_MPSAFE);
1165
	callout_init(&arp_callout, CALLOUT_MPSAFE);
871
	netisr_register(NETISR_ARP, arpintr, &arpintrq, NETISR_MPSAFE);
1166
	netisr_register(NETISR_ARP, arpintr, &arpintrq, NETISR_MPSAFE);
872
	callout_reset(&arp_callout, hz, arptimer, NULL);
1167
	callout_reset(&arp_callout, hz, newarptimer, NULL);
873
}
1168
}
874
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
1169
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
(-)src/sys/netinet/if_ether.h (+27 lines)
Lines 112-117 Link Here
112
int	arpresolve(struct ifnet *ifp, struct rtentry *rt,
112
int	arpresolve(struct ifnet *ifp, struct rtentry *rt,
113
		struct mbuf *m, struct sockaddr *dst, u_char *desten);
113
		struct mbuf *m, struct sockaddr *dst, u_char *desten);
114
void	arp_ifinit(struct ifnet *, struct ifaddr *);
114
void	arp_ifinit(struct ifnet *, struct ifaddr *);
115
116
/*
117
 * Support routines for the new arp table
118
 */
119
struct lltable *lltable_new(struct ifnet *ifp, int af);
120
struct lltable **lltable_free(struct lltable **t);
115
#endif
121
#endif
116
122
123
struct lltable {
124
	struct lltable	*llt_next;
125
	void	*lle_head;	/* pointer to the list of address entries */
126
	int	llt_af;		/* address family */
127
};
128
129
/*
130
 * flags to be passed to arplookup.
131
 */
132
#define LLE_DELETED     0x0001  /* entry must be deleted        */
133
#define LLE_STATIC      0x0002  /* entry is static              */
134
#define LLE_IFADDR      0x0004  /* entry is interface addr      */
135
#define LLA_VALID       0x0008  /* ll_addr is valid             */
136
#define LLE_PROXY       0x0010  /* proxy entry ???              */
137
#define LLE_PUB         0x0020  /* publish entry ???            */
138
#define LLE_CREATE      0x8000  /* create on a lookup miss      */
139
#define LLE_DELETE      0x4000  /* delete on a lookup - match LLE_IFADDR */
140
141
/*
142
 * End of support code for the new arp table
143
 */
117
#endif
144
#endif
(-)src/usr.sbin/arp/arp.c (+11 lines)
Lines 439-444 Link Here
439
		    !(rtm->rtm_flags & RTF_GATEWAY) &&
439
		    !(rtm->rtm_flags & RTF_GATEWAY) &&
440
		    valid_type(sdl->sdl_type) )
440
		    valid_type(sdl->sdl_type) )
441
			break;	/* found it */
441
			break;	/* found it */
442
		/* check the new arp interface */
443
		if (sdl->sdl_family == AF_LINK &&
444
		    !(rtm->rtm_flags & RTF_GATEWAY) &&
445
		    valid_type(sdl->sdl_type) ) {
446
			/*
447
			 * found it. But overwrite the address to make
448
			 * sure that we really get it.
449
			 */
450
			addr->sin_addr.s_addr = dst->sin_addr.s_addr;
451
			break;
452
		}
442
		if (dst->sin_other & SIN_PROXY) {
453
		if (dst->sin_other & SIN_PROXY) {
443
			fprintf(stderr, "delete: cannot locate %s\n",host);
454
			fprintf(stderr, "delete: cannot locate %s\n",host);
444
			return (1);
455
			return (1);

Return to bug 68692