xref: /csrg-svn/sys/net/if.c (revision 10872)
1 /*	if.c	4.25	83/02/10	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/socket.h"
6 #include "../h/protosw.h"
7 #include "../h/time.h"
8 #include "../h/kernel.h"
9 
10 #include "../net/if.h"
11 #include "../net/af.h"
12 
13 int	ifqmaxlen = IFQ_MAXLEN;
14 
15 /*
16  * Network interface utility routines.
17  *
18  * Routines with if_ifwith* names take sockaddr *'s as
19  * parameters.  Other routines take value parameters,
20  * e.g. if_ifwithnet takes the network number.
21  */
22 
23 ifinit()
24 {
25 	register struct ifnet *ifp;
26 
27 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
28 		if (ifp->if_init) {
29 			(*ifp->if_init)(ifp->if_unit);
30 			if (ifp->if_snd.ifq_maxlen == 0)
31 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
32 		}
33 	if_slowtimo();
34 }
35 
36 #if vax
37 /*
38  * Call each interface on a Unibus reset.
39  */
40 ifubareset(uban)
41 	int uban;
42 {
43 	register struct ifnet *ifp;
44 
45 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
46 		if (ifp->if_reset)
47 			(*ifp->if_reset)(uban);
48 }
49 #endif
50 
51 /*
52  * Attach an interface to the
53  * list of "active" interfaces.
54  */
55 if_attach(ifp)
56 	struct ifnet *ifp;
57 {
58 	register struct ifnet **p = &ifnet;
59 
60 	while (*p)
61 		p = &((*p)->if_next);
62 	*p = ifp;
63 }
64 
65 /*
66  * Locate an interface based on a complete address.
67  */
68 /*ARGSUSED*/
69 struct ifnet *
70 if_ifwithaddr(addr)
71 	struct sockaddr *addr;
72 {
73 	register struct ifnet *ifp;
74 
75 #define	equal(a1, a2) \
76 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
77 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
78 		if (ifp->if_addr.sa_family != addr->sa_family)
79 			continue;
80 		if (equal(&ifp->if_addr, addr))
81 			break;
82 		if ((ifp->if_flags & IFF_BROADCAST) &&
83 		    equal(&ifp->if_broadaddr, addr))
84 			break;
85 	}
86 	return (ifp);
87 }
88 
89 /*
90  * Find an interface on a specific network.  If many, choice
91  * is first found.
92  */
93 struct ifnet *
94 if_ifwithnet(addr)
95 	register struct sockaddr *addr;
96 {
97 	register struct ifnet *ifp;
98 	register u_int af = addr->sa_family;
99 	register int (*netmatch)();
100 
101 	if (af >= AF_MAX)
102 		return (0);
103 	netmatch = afswitch[af].af_netmatch;
104 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
105 		if (af != ifp->if_addr.sa_family)
106 			continue;
107 		if ((*netmatch)(addr, &ifp->if_addr))
108 			break;
109 	}
110 	return (ifp);
111 }
112 
113 /*
114  * As above, but parameter is network number.
115  */
116 struct ifnet *
117 if_ifonnetof(net)
118 	register int net;
119 {
120 	register struct ifnet *ifp;
121 
122 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
123 		if (ifp->if_net == net)
124 			break;
125 	return (ifp);
126 }
127 
128 /*
129  * Find an interface using a specific address family
130  */
131 struct ifnet *
132 if_ifwithaf(af)
133 	register int af;
134 {
135 	register struct ifnet *ifp;
136 
137 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
138 		if (ifp->if_addr.sa_family == af)
139 			break;
140 	return (ifp);
141 }
142 
143 /*
144  * Mark an interface down and notify protocols of
145  * the transition.
146  * NOTE: must be called at splnet or eqivalent.
147  */
148 if_down(ifp)
149 	register struct ifnet *ifp;
150 {
151 
152 	ifp->if_flags &= ~IFF_UP;
153 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
154 }
155 
156 /*
157  * Handle interface watchdog timer routines.  Called
158  * from softclock, we decrement timers (if set) and
159  * call the appropriate interface routine on expiration.
160  */
161 if_slowtimo()
162 {
163 	register struct ifnet *ifp;
164 
165 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
166 		if (ifp->if_timer == 0 || --ifp->if_timer)
167 			continue;
168 		if (ifp->if_watchdog)
169 			(*ifp->if_watchdog)(ifp->if_unit);
170 	}
171 	timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
172 }
173