+ case RTM_DELETE:
+ if (lc)
+ RTFREE((struct rtentry *)lc);
+ rt->rt_llinfo = 0;
+ }
+ } else switch (req) {
+ case RTM_ADD:
+ /*
+ * Case 1: This route may come from a route to iface with mask
+ * or from a default route.
+ */
+ if (rt->rt_flags & RTF_CLONING) {
+ register struct ifaddr *ifa;
+ register struct sockaddr *sa;
+ for (ifa = ifp->if_addrlist; ifa; ifa->ifa_next)
+ if ((sa = ifa->ifa_addr)->sa_family == AF_LINK) {
+ if (sa->sa_len > gate->sa.sa_len)
+ log(LOG_DEBUG, "llc_rtrequest: cloning address too small\n");
+ else {
+ Bcopy(sa, gate, gate->sa.sa_len);
+ gate->sdl.sdl_alen = 0;
+ }
+ break;
+ }
+ if (ifa == 0)
+ log(LOG_DEBUG, "llc_rtrequest: can't find LL ifaddr for iface\n");
+ break;
+ }
+ /* FALLTHROUGH */
+ case RTM_RESOLVE:
+ /*
+ * Case 2: This route may come from cloning, or a manual route
+ * add with a LL address.
+ */
+ if (gate->sdl.sdl_family != AF_LINK) {
+ log(LOG_DEBUG, "llc_rtrequest: got non-link non-gateway route\n");
+ break;
+ }
+ if (lc != 0)
+ log(LOG_DEBUG, "llc_rtrequest: losing old rt_llinfo\n");
+ R_Malloc(lc, struct llinfo_llc *, sizeof (*lc));
+ rt->rt_llinfo = (caddr_t)lc;
+ if (lc == 0) {
+ log(LOG_DEBUG, "llc_rtrequest: malloc failed\n");
+ break;
+ }
+ Bzero(lc, sizeof(*lc));
+ lc->lc_rt = rt;
+ rt->rt_flags |= RTF_LLINFO;
+ insque(lc, &llinfo_llc);
+ if (gate->sdl.sdl_alen == sizeof(struct esis_req) + addrlen) {
+ gate->sdl.sdl_alen -= sizeof(struct esis_req);
+ bcopy(addrlen + LLADDR(&gate->sdl),
+ (caddr_t)&lc->lc_er, sizeof(lc->lc_er));
+ } else if (gate->sdl.sdl_alen == addrlen)
+ lc->lc_flags = (SNPA_ES | SNPA_VALID | SNPA_PERM);
+ break;
+ case RTM_DELETE:
+ if (lc == 0 || (rt->rt_flags & RTF_CLONING))
+ return;
+ remque(lc);
+ Free(lc);
+ rt->rt_llinfo = 0;
+ rt->rt_flags &= ~RTF_LLINFO;
+ break;
+ }
+ if (rt->rt_rmx.rmx_mtu == 0) {
+ rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu - LLC_SIZE;
+ }
+}