Commit | Line | Data |
---|---|---|
fb16fdca | 1 | /* if.c 4.25 83/02/10 */ |
1bfd8df7 BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
ee787340 | 5 | #include "../h/socket.h" |
72e4f44e | 6 | #include "../h/protosw.h" |
fb16fdca SL |
7 | #include "../h/time.h" |
8 | #include "../h/kernel.h" | |
9 | ||
1bfd8df7 | 10 | #include "../net/if.h" |
ee787340 | 11 | #include "../net/af.h" |
1bfd8df7 | 12 | |
1e977657 BJ |
13 | int ifqmaxlen = IFQ_MAXLEN; |
14 | ||
ee787340 SL |
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 | ||
85ce71f2 BJ |
23 | ifinit() |
24 | { | |
25 | register struct ifnet *ifp; | |
26 | ||
27 | for (ifp = ifnet; ifp; ifp = ifp->if_next) | |
1e977657 | 28 | if (ifp->if_init) { |
ee787340 | 29 | (*ifp->if_init)(ifp->if_unit); |
1e977657 BJ |
30 | if (ifp->if_snd.ifq_maxlen == 0) |
31 | ifp->if_snd.ifq_maxlen = ifqmaxlen; | |
32 | } | |
5248a70b | 33 | if_slowtimo(); |
85ce71f2 BJ |
34 | } |
35 | ||
14fa60f2 | 36 | #if vax |
ee787340 SL |
37 | /* |
38 | * Call each interface on a Unibus reset. | |
39 | */ | |
85ce71f2 BJ |
40 | ifubareset(uban) |
41 | int uban; | |
42 | { | |
43 | register struct ifnet *ifp; | |
44 | ||
45 | for (ifp = ifnet; ifp; ifp = ifp->if_next) | |
8af3ca7c BJ |
46 | if (ifp->if_reset) |
47 | (*ifp->if_reset)(uban); | |
85ce71f2 | 48 | } |
14fa60f2 | 49 | #endif |
85ce71f2 | 50 | |
ee787340 SL |
51 | /* |
52 | * Attach an interface to the | |
53 | * list of "active" interfaces. | |
54 | */ | |
405c9168 BJ |
55 | if_attach(ifp) |
56 | struct ifnet *ifp; | |
57 | { | |
c4af8b24 | 58 | register struct ifnet **p = &ifnet; |
405c9168 | 59 | |
c4af8b24 BJ |
60 | while (*p) |
61 | p = &((*p)->if_next); | |
62 | *p = ifp; | |
405c9168 BJ |
63 | } |
64 | ||
ee787340 SL |
65 | /* |
66 | * Locate an interface based on a complete address. | |
67 | */ | |
4ad99bae BJ |
68 | /*ARGSUSED*/ |
69 | struct ifnet * | |
ee787340 SL |
70 | if_ifwithaddr(addr) |
71 | struct sockaddr *addr; | |
1bfd8df7 BJ |
72 | { |
73 | register struct ifnet *ifp; | |
74 | ||
ee787340 SL |
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)) | |
1bfd8df7 | 84 | break; |
ee787340 | 85 | } |
1bfd8df7 BJ |
86 | return (ifp); |
87 | } | |
88 | ||
ee787340 SL |
89 | /* |
90 | * Find an interface on a specific network. If many, choice | |
91 | * is first found. | |
92 | */ | |
4ad99bae | 93 | struct ifnet * |
ee787340 SL |
94 | if_ifwithnet(addr) |
95 | register struct sockaddr *addr; | |
96 | { | |
97 | register struct ifnet *ifp; | |
14fa60f2 | 98 | register u_int af = addr->sa_family; |
e65dcd4c | 99 | register int (*netmatch)(); |
ee787340 | 100 | |
e65dcd4c SL |
101 | if (af >= AF_MAX) |
102 | return (0); | |
103 | netmatch = afswitch[af].af_netmatch; | |
ee787340 SL |
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; | |
1bfd8df7 BJ |
119 | { |
120 | register struct ifnet *ifp; | |
1bfd8df7 | 121 | |
1bfd8df7 BJ |
122 | for (ifp = ifnet; ifp; ifp = ifp->if_next) |
123 | if (ifp->if_net == net) | |
124 | break; | |
1bfd8df7 BJ |
125 | return (ifp); |
126 | } | |
127 | ||
ee787340 SL |
128 | /* |
129 | * Find an interface using a specific address family | |
130 | */ | |
8a13b737 | 131 | struct ifnet * |
ee787340 SL |
132 | if_ifwithaf(af) |
133 | register int af; | |
8a13b737 | 134 | { |
ee787340 | 135 | register struct ifnet *ifp; |
8a13b737 | 136 | |
ee787340 SL |
137 | for (ifp = ifnet; ifp; ifp = ifp->if_next) |
138 | if (ifp->if_addr.sa_family == af) | |
139 | break; | |
140 | return (ifp); | |
8a13b737 | 141 | } |
f1b2fa5b | 142 | |
72e4f44e SL |
143 | /* |
144 | * Mark an interface down and notify protocols of | |
145 | * the transition. | |
af0b24db | 146 | * NOTE: must be called at splnet or eqivalent. |
72e4f44e SL |
147 | */ |
148 | if_down(ifp) | |
149 | register struct ifnet *ifp; | |
150 | { | |
5248a70b | 151 | |
72e4f44e SL |
152 | ifp->if_flags &= ~IFF_UP; |
153 | pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); | |
154 | } | |
de602274 SL |
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 | ||
af0b24db SL |
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) | |
de602274 | 169 | (*ifp->if_watchdog)(ifp->if_unit); |
af0b24db | 170 | } |
6e7edb25 | 171 | timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ); |
de602274 | 172 | } |