Annotation of embedaddon/quagga/ospfd/ospf_zebra.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Zebra connect library for OSPFd
3: * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
4: *
5: * This file is part of GNU Zebra.
6: *
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
10: * later version.
11: *
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.
16: *
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
19: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20: * Boston, MA 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "thread.h"
26: #include "command.h"
27: #include "network.h"
28: #include "prefix.h"
29: #include "routemap.h"
30: #include "table.h"
31: #include "stream.h"
32: #include "memory.h"
33: #include "zclient.h"
34: #include "filter.h"
35: #include "plist.h"
36: #include "log.h"
37:
38: #include "ospfd/ospfd.h"
39: #include "ospfd/ospf_interface.h"
40: #include "ospfd/ospf_ism.h"
41: #include "ospfd/ospf_asbr.h"
42: #include "ospfd/ospf_asbr.h"
43: #include "ospfd/ospf_abr.h"
44: #include "ospfd/ospf_lsa.h"
45: #include "ospfd/ospf_dump.h"
46: #include "ospfd/ospf_route.h"
47: #include "ospfd/ospf_zebra.h"
48: #ifdef HAVE_SNMP
49: #include "ospfd/ospf_snmp.h"
50: #endif /* HAVE_SNMP */
51:
52: /* Zebra structure to hold current status. */
53: struct zclient *zclient = NULL;
54:
55: /* For registering threads. */
56: extern struct thread_master *master;
57: struct in_addr router_id_zebra;
58:
59: /* Router-id update message from zebra. */
60: static int
61: ospf_router_id_update_zebra (int command, struct zclient *zclient,
62: zebra_size_t length)
63: {
64: struct ospf *ospf;
65: struct prefix router_id;
66: zebra_router_id_update_read(zclient->ibuf,&router_id);
67:
68: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
69: {
70: char buf[128];
71: prefix2str(&router_id, buf, sizeof(buf));
72: zlog_debug("Zebra rcvd: router id update %s", buf);
73: }
74:
75: router_id_zebra = router_id.u.prefix4;
76:
77: ospf = ospf_lookup ();
78:
79: if (ospf != NULL)
80: ospf_router_id_update (ospf);
81:
82: return 0;
83: }
84:
85: /* Inteface addition message from zebra. */
86: static int
87: ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
88: {
89: struct interface *ifp;
90:
91: ifp = zebra_interface_add_read (zclient->ibuf);
92:
93: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
94: zlog_debug ("Zebra: interface add %s index %d flags %llx metric %d mtu %d",
95: ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
96: ifp->metric, ifp->mtu);
97:
98: assert (ifp->info);
99:
100: if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
101: {
102: SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
103: IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
104: }
105:
106: ospf_if_update (NULL, ifp);
107:
108: #ifdef HAVE_SNMP
109: ospf_snmp_if_update (ifp);
110: #endif /* HAVE_SNMP */
111:
112: return 0;
113: }
114:
115: static int
116: ospf_interface_delete (int command, struct zclient *zclient,
117: zebra_size_t length)
118: {
119: struct interface *ifp;
120: struct stream *s;
121: struct route_node *rn;
122:
123: s = zclient->ibuf;
124: /* zebra_interface_state_read() updates interface structure in iflist */
125: ifp = zebra_interface_state_read (s);
126:
127: if (ifp == NULL)
128: return 0;
129:
130: if (if_is_up (ifp))
131: zlog_warn ("Zebra: got delete of %s, but interface is still up",
132: ifp->name);
133:
134: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
135: zlog_debug
136: ("Zebra: interface delete %s index %d flags %lld metric %d mtu %d",
137: ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
138:
139: #ifdef HAVE_SNMP
140: ospf_snmp_if_delete (ifp);
141: #endif /* HAVE_SNMP */
142:
143: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
144: if (rn->info)
145: ospf_if_free ((struct ospf_interface *) rn->info);
146:
147: ifp->ifindex = IFINDEX_INTERNAL;
148: return 0;
149: }
150:
151: static struct interface *
152: zebra_interface_if_lookup (struct stream *s)
153: {
154: char ifname_tmp[INTERFACE_NAMSIZ];
155:
156: /* Read interface name. */
157: stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
158:
159: /* And look it up. */
160: return if_lookup_by_name_len(ifname_tmp,
161: strnlen(ifname_tmp, INTERFACE_NAMSIZ));
162: }
163:
164: static int
165: ospf_interface_state_up (int command, struct zclient *zclient,
166: zebra_size_t length)
167: {
168: struct interface *ifp;
169: struct ospf_interface *oi;
170: struct route_node *rn;
171:
172: ifp = zebra_interface_if_lookup (zclient->ibuf);
173:
174: if (ifp == NULL)
175: return 0;
176:
177: /* Interface is already up. */
178: if (if_is_operative (ifp))
179: {
180: /* Temporarily keep ifp values. */
181: struct interface if_tmp;
182: memcpy (&if_tmp, ifp, sizeof (struct interface));
183:
184: zebra_interface_if_set_value (zclient->ibuf, ifp);
185:
186: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
187: zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
188:
189: if (if_tmp.bandwidth != ifp->bandwidth)
190: {
191: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
192: zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
193: ifp->name, if_tmp.bandwidth, ifp->bandwidth);
194:
195: ospf_if_recalculate_output_cost (ifp);
196: }
197:
198: if (if_tmp.mtu != ifp->mtu)
199: {
200: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
201: zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
202: ifp->name, if_tmp.mtu, ifp->mtu);
203:
204: /* Must reset the interface (simulate down/up) when MTU changes. */
205: ospf_if_reset(ifp);
206: }
207: return 0;
208: }
209:
210: zebra_interface_if_set_value (zclient->ibuf, ifp);
211:
212: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
213: zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
214:
215: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
216: {
217: if ((oi = rn->info) == NULL)
218: continue;
219:
220: ospf_if_up (oi);
221: }
222:
223: return 0;
224: }
225:
226: static int
227: ospf_interface_state_down (int command, struct zclient *zclient,
228: zebra_size_t length)
229: {
230: struct interface *ifp;
231: struct ospf_interface *oi;
232: struct route_node *node;
233:
234: ifp = zebra_interface_state_read (zclient->ibuf);
235:
236: if (ifp == NULL)
237: return 0;
238:
239: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
240: zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
241:
242: for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
243: {
244: if ((oi = node->info) == NULL)
245: continue;
246: ospf_if_down (oi);
247: }
248:
249: return 0;
250: }
251:
252: static int
253: ospf_interface_address_add (int command, struct zclient *zclient,
254: zebra_size_t length)
255: {
256: struct connected *c;
257:
258: c = zebra_interface_address_read (command, zclient->ibuf);
259:
260: if (c == NULL)
261: return 0;
262:
263: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
264: {
265: char buf[128];
266: prefix2str(c->address, buf, sizeof(buf));
267: zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
268: }
269:
270: ospf_if_update (NULL, c->ifp);
271:
272: #ifdef HAVE_SNMP
273: ospf_snmp_if_update (c->ifp);
274: #endif /* HAVE_SNMP */
275:
276: return 0;
277: }
278:
279: static int
280: ospf_interface_address_delete (int command, struct zclient *zclient,
281: zebra_size_t length)
282: {
283: struct connected *c;
284: struct interface *ifp;
285: struct ospf_interface *oi;
286: struct route_node *rn;
287: struct prefix p;
288:
289: c = zebra_interface_address_read (command, zclient->ibuf);
290:
291: if (c == NULL)
292: return 0;
293:
294: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
295: {
296: char buf[128];
297: prefix2str(c->address, buf, sizeof(buf));
298: zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf);
299: }
300:
301: ifp = c->ifp;
302: p = *c->address;
303: p.prefixlen = IPV4_MAX_PREFIXLEN;
304:
305: rn = route_node_lookup (IF_OIFS (ifp), &p);
306: if (!rn)
307: {
308: connected_free (c);
309: return 0;
310: }
311:
312: assert (rn->info);
313: oi = rn->info;
314:
315: /* Call interface hook functions to clean up */
316: ospf_if_free (oi);
317:
318: #ifdef HAVE_SNMP
319: ospf_snmp_if_update (c->ifp);
320: #endif /* HAVE_SNMP */
321:
322: connected_free (c);
323:
324: return 0;
325: }
326:
327: void
328: ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
329: {
330: u_char message;
331: u_char distance;
332: u_char flags;
333: int psize;
334: struct stream *s;
335: struct ospf_path *path;
336: struct listnode *node;
337:
338: if (zclient->redist[ZEBRA_ROUTE_OSPF])
339: {
340: message = 0;
341: flags = 0;
342:
343: /* OSPF pass nexthop and metric */
344: SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
345: SET_FLAG (message, ZAPI_MESSAGE_METRIC);
346:
347: /* Distance value. */
348: distance = ospf_distance_apply (p, or);
349: if (distance)
350: SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
351:
352: /* Make packet. */
353: s = zclient->obuf;
354: stream_reset (s);
355:
356: /* Put command, type, flags, message. */
357: zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
358: stream_putc (s, ZEBRA_ROUTE_OSPF);
359: stream_putc (s, flags);
360: stream_putc (s, message);
1.1.1.2 ! misho 361: stream_putw (s, SAFI_UNICAST);
1.1 misho 362:
363: /* Put prefix information. */
364: psize = PSIZE (p->prefixlen);
365: stream_putc (s, p->prefixlen);
366: stream_write (s, (u_char *) & p->prefix, psize);
367:
368: /* Nexthop count. */
369: stream_putc (s, or->paths->count);
370:
371: /* Nexthop, ifindex, distance and metric information. */
372: for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
373: {
374: if (path->nexthop.s_addr != INADDR_ANY)
375: {
376: stream_putc (s, ZEBRA_NEXTHOP_IPV4);
377: stream_put_in_addr (s, &path->nexthop);
378: }
379: else
380: {
381: stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
382: if (path->ifindex)
383: stream_putl (s, path->ifindex);
384: else
385: stream_putl (s, 0);
386: }
387:
388: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
389: {
390: char buf[2][INET_ADDRSTRLEN];
391: zlog_debug("Zebra: Route add %s/%d nexthop %s",
392: inet_ntop(AF_INET, &p->prefix,
393: buf[0], sizeof(buf[0])),
394: p->prefixlen,
395: inet_ntop(AF_INET, &path->nexthop,
396: buf[1], sizeof(buf[1])));
397: }
398: }
399:
400: if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
401: stream_putc (s, distance);
402: if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
403: {
404: if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
405: stream_putl (s, or->cost + or->u.ext.type2_cost);
406: else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
407: stream_putl (s, or->u.ext.type2_cost);
408: else
409: stream_putl (s, or->cost);
410: }
411:
412: stream_putw_at (s, 0, stream_get_endp (s));
413:
414: zclient_send_message(zclient);
415: }
416: }
417:
418: void
419: ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
420: {
421: struct zapi_ipv4 api;
422: struct ospf_path *path;
423: struct in_addr *nexthop;
424: struct listnode *node, *nnode;
425:
426: if (zclient->redist[ZEBRA_ROUTE_OSPF])
427: {
428: api.type = ZEBRA_ROUTE_OSPF;
429: api.flags = 0;
430: api.message = 0;
1.1.1.2 ! misho 431: api.safi = SAFI_UNICAST;
1.1 misho 432: api.ifindex_num = 0;
433: api.nexthop_num = 0;
434:
435: for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
436: {
437: if (path->nexthop.s_addr != INADDR_ANY)
438: {
439: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
440: api.nexthop_num = 1;
441: nexthop = &path->nexthop;
442: api.nexthop = &nexthop;
443: }
444: else if (if_lookup_by_index(path->ifindex))
445: {
446: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
447: api.ifindex_num = 1;
448: api.ifindex = &path->ifindex;
449: }
450: else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
451: {
452: zlog_debug("Zebra: no ifp %s %d",
453: inet_ntoa(p->prefix),
454: p->prefixlen);
455: }
456:
457: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
458:
459: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
460: {
461: char buf[2][INET_ADDRSTRLEN];
462: zlog_debug("Zebra: Route delete %s/%d nexthop %s",
463: inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])),
464: p->prefixlen,
465: inet_ntop(AF_INET, *api.nexthop,
466: buf[1], sizeof(buf[1])));
467: }
468: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
469: {
470: zlog_debug ("Zebra: Route delete %s/%d ifindex %d",
471: inet_ntoa (p->prefix),
472: p->prefixlen, *api.ifindex);
473: }
474: }
475: }
476: }
477:
478: void
479: ospf_zebra_add_discard (struct prefix_ipv4 *p)
480: {
481: struct zapi_ipv4 api;
482:
483: if (zclient->redist[ZEBRA_ROUTE_OSPF])
484: {
485: api.type = ZEBRA_ROUTE_OSPF;
486: api.flags = ZEBRA_FLAG_BLACKHOLE;
487: api.message = 0;
1.1.1.2 ! misho 488: api.safi = SAFI_UNICAST;
1.1 misho 489: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
490: api.nexthop_num = 0;
491: api.ifindex_num = 0;
492:
493: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
494:
495: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
496: zlog_debug ("Zebra: Route add discard %s/%d",
497: inet_ntoa (p->prefix), p->prefixlen);
498: }
499: }
500:
501: void
502: ospf_zebra_delete_discard (struct prefix_ipv4 *p)
503: {
504: struct zapi_ipv4 api;
505:
506: if (zclient->redist[ZEBRA_ROUTE_OSPF])
507: {
508: api.type = ZEBRA_ROUTE_OSPF;
509: api.flags = ZEBRA_FLAG_BLACKHOLE;
510: api.message = 0;
1.1.1.2 ! misho 511: api.safi = SAFI_UNICAST;
1.1 misho 512: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
513: api.nexthop_num = 0;
514: api.ifindex_num = 0;
515:
516: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
517:
518: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
519: zlog_debug ("Zebra: Route delete discard %s/%d",
520: inet_ntoa (p->prefix), p->prefixlen);
521:
522: }
523: }
524:
525: int
526: ospf_is_type_redistributed (int type)
527: {
528: return (DEFAULT_ROUTE_TYPE (type)) ?
529: zclient->default_information : zclient->redist[type];
530: }
531:
532: int
533: ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
534: {
535: int force = 0;
536:
537: if (ospf_is_type_redistributed (type))
538: {
539: if (mtype != ospf->dmetric[type].type)
540: {
541: ospf->dmetric[type].type = mtype;
542: force = LSA_REFRESH_FORCE;
543: }
544: if (mvalue != ospf->dmetric[type].value)
545: {
546: ospf->dmetric[type].value = mvalue;
547: force = LSA_REFRESH_FORCE;
548: }
549:
550: ospf_external_lsa_refresh_type (ospf, type, force);
551:
552: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
553: zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
554: ospf_redist_string(type),
555: metric_type (ospf, type), metric_value (ospf, type));
556:
557: return CMD_SUCCESS;
558: }
559:
560: ospf->dmetric[type].type = mtype;
561: ospf->dmetric[type].value = mvalue;
562:
563: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
564:
565: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
566: zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
567: ospf_redist_string(type),
568: metric_type (ospf, type), metric_value (ospf, type));
569:
570: ospf_asbr_status_update (ospf, ++ospf->redistribute);
571:
572: return CMD_SUCCESS;
573: }
574:
575: int
576: ospf_redistribute_unset (struct ospf *ospf, int type)
577: {
578: if (type == zclient->redist_default)
579: return CMD_SUCCESS;
580:
581: if (!ospf_is_type_redistributed (type))
582: return CMD_SUCCESS;
583:
584: zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
585:
586: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
587: zlog_debug ("Redistribute[%s]: Stop",
588: ospf_redist_string(type));
589:
590: ospf->dmetric[type].type = -1;
591: ospf->dmetric[type].value = -1;
592:
593: /* Remove the routes from OSPF table. */
594: ospf_redistribute_withdraw (ospf, type);
595:
596: ospf_asbr_status_update (ospf, --ospf->redistribute);
597:
598: return CMD_SUCCESS;
599: }
600:
601: int
602: ospf_redistribute_default_set (struct ospf *ospf, int originate,
603: int mtype, int mvalue)
604: {
605: ospf->default_originate = originate;
606: ospf->dmetric[DEFAULT_ROUTE].type = mtype;
607: ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
608:
609: if (ospf_is_type_redistributed (DEFAULT_ROUTE))
610: {
611: /* if ospf->default_originate changes value, is calling
612: ospf_external_lsa_refresh_default sufficient to implement
613: the change? */
614: ospf_external_lsa_refresh_default (ospf);
615:
616: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
617: zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
618: ospf_redist_string(DEFAULT_ROUTE),
619: metric_type (ospf, DEFAULT_ROUTE),
620: metric_value (ospf, DEFAULT_ROUTE));
621: return CMD_SUCCESS;
622: }
623:
624: zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
625:
626: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
627: zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
628: metric_type (ospf, DEFAULT_ROUTE),
629: metric_value (ospf, DEFAULT_ROUTE));
630:
631: if (ospf->router_id.s_addr == 0)
632: ospf->external_origin |= (1 << DEFAULT_ROUTE);
633: else
634: thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
635:
636: ospf_asbr_status_update (ospf, ++ospf->redistribute);
637:
638: return CMD_SUCCESS;
639: }
640:
641: int
642: ospf_redistribute_default_unset (struct ospf *ospf)
643: {
644: if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
645: return CMD_SUCCESS;
646:
647: ospf->default_originate = DEFAULT_ORIGINATE_NONE;
648: ospf->dmetric[DEFAULT_ROUTE].type = -1;
649: ospf->dmetric[DEFAULT_ROUTE].value = -1;
650:
651: zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
652:
653: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
654: zlog_debug ("Redistribute[DEFAULT]: Stop");
655:
656: ospf_asbr_status_update (ospf, --ospf->redistribute);
657:
658: return CMD_SUCCESS;
659: }
660:
661: static int
662: ospf_external_lsa_originate_check (struct ospf *ospf,
663: struct external_info *ei)
664: {
665: /* If prefix is multicast, then do not originate LSA. */
666: if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
667: {
668: zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
669: "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
670: return 0;
671: }
672:
673: /* Take care of default-originate. */
674: if (is_prefix_default (&ei->p))
675: if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
676: {
677: zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
678: "for default");
679: return 0;
680: }
681:
682: return 1;
683: }
684:
685: /* If connected prefix is OSPF enable interface, then do not announce. */
686: int
687: ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
688: {
689: struct listnode *node;
690: struct ospf_interface *oi;
691:
692:
693: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
694: if (prefix_match (oi->address, (struct prefix *) &ei->p))
695: return 0;
696: return 1;
697: }
698:
699: /* return 1 if external LSA must be originated, 0 otherwise */
700: int
701: ospf_redistribute_check (struct ospf *ospf,
702: struct external_info *ei, int *changed)
703: {
704: struct route_map_set_values save_values;
705: struct prefix_ipv4 *p = &ei->p;
706: u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
707:
708: if (changed)
709: *changed = 0;
710:
711: if (!ospf_external_lsa_originate_check (ospf, ei))
712: return 0;
713:
714: /* Take care connected route. */
715: if (type == ZEBRA_ROUTE_CONNECT &&
716: !ospf_distribute_check_connected (ospf, ei))
717: return 0;
718:
719: if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
720: /* distirbute-list exists, but access-list may not? */
721: if (DISTRIBUTE_LIST (ospf, type))
722: if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
723: {
724: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
725: zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
726: ospf_redist_string(type),
727: inet_ntoa (p->prefix), p->prefixlen);
728: return 0;
729: }
730:
731: save_values = ei->route_map_set;
732: ospf_reset_route_map_set_values (&ei->route_map_set);
733:
734: /* apply route-map if needed */
735: if (ROUTEMAP_NAME (ospf, type))
736: {
737: int ret;
738:
739: ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
740: RMAP_OSPF, ei);
741:
742: if (ret == RMAP_DENYMATCH)
743: {
744: ei->route_map_set = save_values;
745: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
746: zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
747: ospf_redist_string(type),
748: inet_ntoa (p->prefix), p->prefixlen);
749: return 0;
750: }
751:
752: /* check if 'route-map set' changed something */
753: if (changed)
754: *changed = !ospf_route_map_set_compare (&ei->route_map_set,
755: &save_values);
756: }
757:
758: return 1;
759: }
760:
761: /* OSPF route-map set for redistribution */
762: void
763: ospf_routemap_set (struct ospf *ospf, int type, const char *name)
764: {
765: if (ROUTEMAP_NAME (ospf, type))
766: free (ROUTEMAP_NAME (ospf, type));
767:
768: ROUTEMAP_NAME (ospf, type) = strdup (name);
769: ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
770: }
771:
772: void
773: ospf_routemap_unset (struct ospf *ospf, int type)
774: {
775: if (ROUTEMAP_NAME (ospf, type))
776: free (ROUTEMAP_NAME (ospf, type));
777:
778: ROUTEMAP_NAME (ospf, type) = NULL;
779: ROUTEMAP (ospf, type) = NULL;
780: }
781:
782: /* Zebra route add and delete treatment. */
783: static int
784: ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
785: zebra_size_t length)
786: {
787: struct stream *s;
788: struct zapi_ipv4 api;
789: unsigned long ifindex;
790: struct in_addr nexthop;
791: struct prefix_ipv4 p;
792: struct external_info *ei;
793: struct ospf *ospf;
794:
795: s = zclient->ibuf;
796: ifindex = 0;
797: nexthop.s_addr = 0;
798:
799: /* Type, flags, message. */
800: api.type = stream_getc (s);
801: api.flags = stream_getc (s);
802: api.message = stream_getc (s);
803:
804: /* IPv4 prefix. */
805: memset (&p, 0, sizeof (struct prefix_ipv4));
806: p.family = AF_INET;
807: p.prefixlen = stream_getc (s);
808: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
809:
810: if (IPV4_NET127(ntohl(p.prefix.s_addr)))
811: return 0;
812:
813: /* Nexthop, ifindex, distance, metric. */
814: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
815: {
816: api.nexthop_num = stream_getc (s);
817: nexthop.s_addr = stream_get_ipv4 (s);
818: }
819: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
820: {
821: api.ifindex_num = stream_getc (s);
822: /* XXX assert(api.ifindex_num == 1); */
823: ifindex = stream_getl (s);
824: }
825: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
826: api.distance = stream_getc (s);
827: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
828: api.metric = stream_getl (s);
829:
830: ospf = ospf_lookup ();
831: if (ospf == NULL)
832: return 0;
833:
834: if (command == ZEBRA_IPV4_ROUTE_ADD)
835: {
836: /* XXX|HACK|TODO|FIXME:
837: * Maybe we should ignore reject/blackhole routes? Testing shows that
838: * there is no problems though and this is only way to "summarize"
839: * routes in ASBR at the moment. Maybe we need just a better generalised
840: * solution for these types?
841: *
842: * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
843: * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
844: * return 0;
845: */
846:
847: ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
848:
849: if (ospf->router_id.s_addr == 0)
850: /* Set flags to generate AS-external-LSA originate event
851: for each redistributed protocols later. */
852: ospf->external_origin |= (1 << api.type);
853: else
854: {
855: if (ei)
856: {
857: if (is_prefix_default (&p))
858: ospf_external_lsa_refresh_default (ospf);
859: else
860: {
861: struct ospf_lsa *current;
862:
863: current = ospf_external_info_find_lsa (ospf, &ei->p);
864: if (!current)
865: ospf_external_lsa_originate (ospf, ei);
866: else if (IS_LSA_MAXAGE (current))
867: ospf_external_lsa_refresh (ospf, current,
868: ei, LSA_REFRESH_FORCE);
869: else
870: zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
871: inet_ntoa (p.prefix));
872: }
873: }
874: }
875: }
876: else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
877: {
878: ospf_external_info_delete (api.type, p);
879: if (is_prefix_default (&p))
880: ospf_external_lsa_refresh_default (ospf);
881: else
882: ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
883: }
884:
885: return 0;
886: }
887:
888:
889: int
890: ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
891: {
892: /* Lookup access-list for distribute-list. */
893: DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
894:
895: /* Clear previous distribute-name. */
896: if (DISTRIBUTE_NAME (ospf, type))
897: free (DISTRIBUTE_NAME (ospf, type));
898:
899: /* Set distribute-name. */
900: DISTRIBUTE_NAME (ospf, type) = strdup (name);
901:
902: /* If access-list have been set, schedule update timer. */
903: if (DISTRIBUTE_LIST (ospf, type))
904: ospf_distribute_list_update (ospf, type);
905:
906: return CMD_SUCCESS;
907: }
908:
909: int
910: ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
911: {
912: /* Schedule update timer. */
913: if (DISTRIBUTE_LIST (ospf, type))
914: ospf_distribute_list_update (ospf, type);
915:
916: /* Unset distribute-list. */
917: DISTRIBUTE_LIST (ospf, type) = NULL;
918:
919: /* Clear distribute-name. */
920: if (DISTRIBUTE_NAME (ospf, type))
921: free (DISTRIBUTE_NAME (ospf, type));
922:
923: DISTRIBUTE_NAME (ospf, type) = NULL;
924:
925: return CMD_SUCCESS;
926: }
927:
928: /* distribute-list update timer. */
929: static int
930: ospf_distribute_list_update_timer (struct thread *thread)
931: {
932: struct route_node *rn;
933: struct external_info *ei;
934: struct route_table *rt;
935: struct ospf_lsa *lsa;
936: int type, default_refresh = 0;
937: struct ospf *ospf;
938:
939: ospf = ospf_lookup ();
940: if (ospf == NULL)
941: return 0;
942:
943: ospf->t_distribute_update = NULL;
944:
945: zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
946:
947: /* foreach all external info. */
948: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
949: {
950: rt = EXTERNAL_INFO (type);
951: if (!rt)
952: continue;
953: for (rn = route_top (rt); rn; rn = route_next (rn))
954: if ((ei = rn->info) != NULL)
955: {
956: if (is_prefix_default (&ei->p))
957: default_refresh = 1;
958: else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
959: ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
960: else
961: ospf_external_lsa_originate (ospf, ei);
962: }
963: }
964: if (default_refresh)
965: ospf_external_lsa_refresh_default (ospf);
966: return 0;
967: }
968:
969: #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
970:
971: /* Update distribute-list and set timer to apply access-list. */
972: void
973: ospf_distribute_list_update (struct ospf *ospf, int type)
974: {
975: struct route_table *rt;
976:
977: /* External info does not exist. */
978: if (!(rt = EXTERNAL_INFO (type)))
979: return;
980:
981: /* If exists previously invoked thread, then let it continue. */
982: if (ospf->t_distribute_update)
983: return;
984:
985: /* Set timer. */
986: ospf->t_distribute_update =
987: thread_add_timer (master, ospf_distribute_list_update_timer,
988: (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
989: }
990:
991: /* If access-list is updated, apply some check. */
992: static void
993: ospf_filter_update (struct access_list *access)
994: {
995: struct ospf *ospf;
996: int type;
997: int abr_inv = 0;
998: struct ospf_area *area;
999: struct listnode *node;
1000:
1001: /* If OSPF instatnce does not exist, return right now. */
1002: ospf = ospf_lookup ();
1003: if (ospf == NULL)
1004: return;
1005:
1006: /* Update distribute-list, and apply filter. */
1007: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1008: {
1009: if (ROUTEMAP (ospf, type) != NULL)
1010: {
1011: /* if route-map is not NULL it may be using this access list */
1012: ospf_distribute_list_update (ospf, type);
1013: continue;
1014: }
1015:
1016: /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
1017: * but no distribute list. */
1018: if (type == ZEBRA_ROUTE_MAX)
1019: break;
1020:
1021: if (DISTRIBUTE_NAME (ospf, type))
1022: {
1023: /* Keep old access-list for distribute-list. */
1024: struct access_list *old = DISTRIBUTE_LIST (ospf, type);
1025:
1026: /* Update access-list for distribute-list. */
1027: DISTRIBUTE_LIST (ospf, type) =
1028: access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
1029:
1030: /* No update for this distribute type. */
1031: if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
1032: continue;
1033:
1034: /* Schedule distribute-list update timer. */
1035: if (DISTRIBUTE_LIST (ospf, type) == NULL ||
1036: strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
1037: ospf_distribute_list_update (ospf, type);
1038: }
1039: }
1040:
1041: /* Update Area access-list. */
1042: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1043: {
1044: if (EXPORT_NAME (area))
1045: {
1046: EXPORT_LIST (area) = NULL;
1047: abr_inv++;
1048: }
1049:
1050: if (IMPORT_NAME (area))
1051: {
1052: IMPORT_LIST (area) = NULL;
1053: abr_inv++;
1054: }
1055: }
1056:
1057: /* Schedule ABR tasks -- this will be changed -- takada. */
1058: if (IS_OSPF_ABR (ospf) && abr_inv)
1059: ospf_schedule_abr_task (ospf);
1060: }
1061:
1062: /* If prefix-list is updated, do some updates. */
1063: void
1064: ospf_prefix_list_update (struct prefix_list *plist)
1065: {
1066: struct ospf *ospf;
1067: int type;
1068: int abr_inv = 0;
1069: struct ospf_area *area;
1070: struct listnode *node;
1071:
1072: /* If OSPF instatnce does not exist, return right now. */
1073: ospf = ospf_lookup ();
1074: if (ospf == NULL)
1075: return;
1076:
1077: /* Update all route-maps which are used as redistribution filters.
1078: * They might use prefix-list.
1079: */
1080: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1081: {
1082: if (ROUTEMAP (ospf, type) != NULL)
1083: {
1084: /* If route-map is not NULL it may be using this prefix list */
1085: ospf_distribute_list_update (ospf, type);
1086: continue;
1087: }
1088: }
1089:
1090: /* Update area filter-lists. */
1091: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1092: {
1093: /* Update filter-list in. */
1094: if (PREFIX_NAME_IN (area))
1095: if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
1096: {
1097: PREFIX_LIST_IN (area) =
1098: prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
1099: abr_inv++;
1100: }
1101:
1102: /* Update filter-list out. */
1103: if (PREFIX_NAME_OUT (area))
1104: if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
1105: {
1106: PREFIX_LIST_IN (area) =
1107: prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
1108: abr_inv++;
1109: }
1110: }
1111:
1112: /* Schedule ABR task. */
1113: if (IS_OSPF_ABR (ospf) && abr_inv)
1114: ospf_schedule_abr_task (ospf);
1115: }
1116:
1117: static struct ospf_distance *
1118: ospf_distance_new (void)
1119: {
1120: return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1121: }
1122:
1123: static void
1124: ospf_distance_free (struct ospf_distance *odistance)
1125: {
1126: XFREE (MTYPE_OSPF_DISTANCE, odistance);
1127: }
1128:
1129: int
1130: ospf_distance_set (struct vty *vty, struct ospf *ospf,
1131: const char *distance_str,
1132: const char *ip_str,
1133: const char *access_list_str)
1134: {
1135: int ret;
1136: struct prefix_ipv4 p;
1137: u_char distance;
1138: struct route_node *rn;
1139: struct ospf_distance *odistance;
1140:
1141: ret = str2prefix_ipv4 (ip_str, &p);
1142: if (ret == 0)
1143: {
1144: vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1145: return CMD_WARNING;
1146: }
1147:
1148: distance = atoi (distance_str);
1149:
1150: /* Get OSPF distance node. */
1151: rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
1152: if (rn->info)
1153: {
1154: odistance = rn->info;
1155: route_unlock_node (rn);
1156: }
1157: else
1158: {
1159: odistance = ospf_distance_new ();
1160: rn->info = odistance;
1161: }
1162:
1163: /* Set distance value. */
1164: odistance->distance = distance;
1165:
1166: /* Reset access-list configuration. */
1167: if (odistance->access_list)
1168: {
1169: free (odistance->access_list);
1170: odistance->access_list = NULL;
1171: }
1172: if (access_list_str)
1173: odistance->access_list = strdup (access_list_str);
1174:
1175: return CMD_SUCCESS;
1176: }
1177:
1178: int
1179: ospf_distance_unset (struct vty *vty, struct ospf *ospf,
1180: const char *distance_str,
1181: const char *ip_str, char
1182: const *access_list_str)
1183: {
1184: int ret;
1185: struct prefix_ipv4 p;
1186: u_char distance;
1187: struct route_node *rn;
1188: struct ospf_distance *odistance;
1189:
1190: ret = str2prefix_ipv4 (ip_str, &p);
1191: if (ret == 0)
1192: {
1193: vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1194: return CMD_WARNING;
1195: }
1196:
1197: distance = atoi (distance_str);
1198:
1199: rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
1200: if (!rn)
1201: {
1202: vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1203: return CMD_WARNING;
1204: }
1205:
1206: odistance = rn->info;
1207:
1208: if (odistance->access_list)
1209: free (odistance->access_list);
1210: ospf_distance_free (odistance);
1211:
1212: rn->info = NULL;
1213: route_unlock_node (rn);
1214: route_unlock_node (rn);
1215:
1216: return CMD_SUCCESS;
1217: }
1218:
1219: void
1220: ospf_distance_reset (struct ospf *ospf)
1221: {
1222: struct route_node *rn;
1223: struct ospf_distance *odistance;
1224:
1225: for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
1226: if ((odistance = rn->info) != NULL)
1227: {
1228: if (odistance->access_list)
1229: free (odistance->access_list);
1230: ospf_distance_free (odistance);
1231: rn->info = NULL;
1232: route_unlock_node (rn);
1233: }
1234: }
1235:
1236: u_char
1237: ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1238: {
1239: struct ospf *ospf;
1240:
1241: ospf = ospf_lookup ();
1242: if (ospf == NULL)
1243: return 0;
1244:
1245: if (ospf->distance_intra)
1246: if (or->path_type == OSPF_PATH_INTRA_AREA)
1247: return ospf->distance_intra;
1248:
1249: if (ospf->distance_inter)
1250: if (or->path_type == OSPF_PATH_INTER_AREA)
1251: return ospf->distance_inter;
1252:
1253: if (ospf->distance_external)
1254: if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
1255: || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1256: return ospf->distance_external;
1257:
1258: if (ospf->distance_all)
1259: return ospf->distance_all;
1260:
1261: return 0;
1262: }
1263:
1264: void
1265: ospf_zebra_init ()
1266: {
1267: /* Allocate zebra structure. */
1268: zclient = zclient_new ();
1269: zclient_init (zclient, ZEBRA_ROUTE_OSPF);
1270: zclient->router_id_update = ospf_router_id_update_zebra;
1271: zclient->interface_add = ospf_interface_add;
1272: zclient->interface_delete = ospf_interface_delete;
1273: zclient->interface_up = ospf_interface_state_up;
1274: zclient->interface_down = ospf_interface_state_down;
1275: zclient->interface_address_add = ospf_interface_address_add;
1276: zclient->interface_address_delete = ospf_interface_address_delete;
1277: zclient->ipv4_route_add = ospf_zebra_read_ipv4;
1278: zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
1279:
1280: access_list_add_hook (ospf_filter_update);
1281: access_list_delete_hook (ospf_filter_update);
1282: prefix_list_add_hook (ospf_prefix_list_update);
1283: prefix_list_delete_hook (ospf_prefix_list_update);
1284: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>