2 * Address linked list routine.
3 * Copyright (C) 1997, 98 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "zebra/zserv.h"
34 #include "zebra/redistribute.h"
36 /* If same interface address is already exist... */
38 connected_check_ipv4 (struct interface *ifp, struct prefix *p)
40 struct connected *ifc;
43 for (node = listhead (ifp->connected); node; node = nextnode (node))
47 if (prefix_same (ifc->address, p))
53 /* Called from if_up(). */
55 connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
58 struct prefix_ipv4 *addr;
59 struct prefix_ipv4 *dest;
61 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
64 addr = (struct prefix_ipv4 *) ifc->address;
65 dest = (struct prefix_ipv4 *) ifc->destination;
67 memset (&p, 0, sizeof (struct prefix_ipv4));
69 p.prefixlen = addr->prefixlen;
71 /* Point-to-point check. */
72 if (if_is_pointopoint (ifp))
73 p.prefix = dest->prefix;
75 p.prefix = addr->prefix;
77 /* Apply mask to the network. */
80 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
82 if (prefix_ipv4_any (&p))
85 rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0);
90 /* Add connected IPv4 route to the interface. */
92 connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
93 int prefixlen, struct in_addr *broad, char *label)
95 struct prefix_ipv4 *p;
96 struct connected *ifc;
97 struct connected *current;
99 /* Make connected structure. */
100 ifc = connected_new ();
104 /* Allocate new connected address. */
105 p = prefix_ipv4_new ();
108 p->prefixlen = prefixlen;
109 ifc->address = (struct prefix *) p;
111 /* If there is broadcast or pointopoint address. */
114 p = prefix_ipv4_new ();
117 ifc->destination = (struct prefix *) p;
120 /* Label of this address. */
122 ifc->label = strdup (label);
124 /* Check same connected route. */
125 current = connected_check_ipv4 (ifp, (struct prefix *) ifc->address);
128 connected_free (ifc);
133 listnode_add (ifp->connected, ifc);
136 /* Update interface address information to protocol daemon. */
137 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
139 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
141 zebra_interface_address_add_update (ifp, ifc);
144 connected_up_ipv4 (ifp, ifc);
149 connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
151 struct prefix_ipv4 p;
152 struct prefix_ipv4 *addr;
153 struct prefix_ipv4 *dest;
155 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
158 addr = (struct prefix_ipv4 *)ifc->address;
159 dest = (struct prefix_ipv4 *)ifc->destination;
161 memset (&p, 0, sizeof (struct prefix_ipv4));
163 p.prefixlen = addr->prefixlen;
165 if (if_is_pointopoint (ifp))
166 p.prefix = dest->prefix;
168 p.prefix = addr->prefix;
170 /* Apply mask to the network. */
171 apply_mask_ipv4 (&p);
173 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
175 if (prefix_ipv4_any (&p))
178 rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
183 /* Delete connected IPv4 route to the interface. */
185 connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
186 int prefixlen, struct in_addr *broad, char *label)
188 struct prefix_ipv4 p;
189 struct connected *ifc;
191 memset (&p, 0, sizeof (struct prefix_ipv4));
194 p.prefixlen = prefixlen;
196 ifc = connected_check_ipv4 (ifp, (struct prefix *) &p);
200 /* Update interface address information to protocol daemon. */
201 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
203 zebra_interface_address_delete_update (ifp, ifc);
205 connected_down_ipv4 (ifp, ifc);
207 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
210 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
212 listnode_delete (ifp->connected, ifc);
213 connected_free (ifc);
218 /* If same interface address is already exist... */
220 connected_check_ipv6 (struct interface *ifp, struct prefix *p)
222 struct connected *ifc;
225 for (node = listhead (ifp->connected); node; node = nextnode (node))
227 ifc = getdata (node);
229 if (prefix_same (ifc->address, p))
236 connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
238 struct prefix_ipv6 p;
239 struct prefix_ipv6 *addr;
240 struct prefix_ipv6 *dest;
242 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
245 addr = (struct prefix_ipv6 *) ifc->address;
246 dest = (struct prefix_ipv6 *) ifc->destination;
248 memset (&p, 0, sizeof (struct prefix_ipv6));
250 p.prefixlen = addr->prefixlen;
252 if (if_is_pointopoint (ifp) && dest)
254 if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
255 p.prefix = addr->prefix;
257 p.prefix = dest->prefix;
260 p.prefix = addr->prefix;
262 /* Apply mask to the network. */
263 apply_mask_ipv6 (&p);
265 if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
268 rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
273 /* Add connected IPv6 route to the interface. */
275 connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr,
276 int prefixlen, struct in6_addr *broad)
278 struct prefix_ipv6 *p;
279 struct connected *ifc;
280 struct connected *current;
282 /* Make connected structure. */
283 ifc = connected_new ();
286 /* Allocate new connected address. */
287 p = prefix_ipv6_new ();
288 p->family = AF_INET6;
289 IPV6_ADDR_COPY (&p->prefix, addr);
290 p->prefixlen = prefixlen;
291 ifc->address = (struct prefix *) p;
293 /* If there is broadcast or pointopoint address. */
296 p = prefix_ipv6_new ();
297 p->family = AF_INET6;
298 IPV6_ADDR_COPY (&p->prefix, broad);
299 ifc->destination = (struct prefix *) p;
302 current = connected_check_ipv6 (ifp, (struct prefix *) ifc->address);
305 connected_free (ifc);
310 listnode_add (ifp->connected, ifc);
313 /* Update interface address information to protocol daemon. */
314 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
316 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
318 zebra_interface_address_add_update (ifp, ifc);
321 connected_up_ipv6 (ifp, ifc);
326 connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
328 struct prefix_ipv6 p;
329 struct prefix_ipv6 *addr;
330 struct prefix_ipv6 *dest;
332 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
335 addr = (struct prefix_ipv6 *) ifc->address;
336 dest = (struct prefix_ipv6 *) ifc->destination;
338 memset (&p, 0, sizeof (struct prefix_ipv6));
340 p.prefixlen = addr->prefixlen;
342 if (if_is_pointopoint (ifp) && dest)
344 if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
345 p.prefix = addr->prefix;
347 p.prefix = dest->prefix;
350 p.prefix = addr->prefix;
352 apply_mask_ipv6 (&p);
354 if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
357 rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
363 connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
364 int prefixlen, struct in6_addr *broad)
366 struct prefix_ipv6 p;
367 struct connected *ifc;
369 memset (&p, 0, sizeof (struct prefix_ipv6));
371 memcpy (&p.prefix, address, sizeof (struct in6_addr));
372 p.prefixlen = prefixlen;
374 ifc = connected_check_ipv6 (ifp, (struct prefix *) &p);
378 /* Update interface address information to protocol daemon. */
379 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
381 zebra_interface_address_delete_update (ifp, ifc);
383 connected_down_ipv6 (ifp, ifc);
385 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
388 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
390 listnode_delete (ifp->connected, ifc);
391 connected_free (ifc);
394 #endif /* HAVE_IPV6 */