Annotation of embedaddon/quagga/ospfd/ospf_zebra.c, revision 1.1.1.1
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);
361:
362: /* Put prefix information. */
363: psize = PSIZE (p->prefixlen);
364: stream_putc (s, p->prefixlen);
365: stream_write (s, (u_char *) & p->prefix, psize);
366:
367: /* Nexthop count. */
368: stream_putc (s, or->paths->count);
369:
370: /* Nexthop, ifindex, distance and metric information. */
371: for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
372: {
373: if (path->nexthop.s_addr != INADDR_ANY)
374: {
375: stream_putc (s, ZEBRA_NEXTHOP_IPV4);
376: stream_put_in_addr (s, &path->nexthop);
377: }
378: else
379: {
380: stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
381: if (path->ifindex)
382: stream_putl (s, path->ifindex);
383: else
384: stream_putl (s, 0);
385: }
386:
387: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
388: {
389: char buf[2][INET_ADDRSTRLEN];
390: zlog_debug("Zebra: Route add %s/%d nexthop %s",
391: inet_ntop(AF_INET, &p->prefix,
392: buf[0], sizeof(buf[0])),
393: p->prefixlen,
394: inet_ntop(AF_INET, &path->nexthop,
395: buf[1], sizeof(buf[1])));
396: }
397: }
398:
399: if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
400: stream_putc (s, distance);
401: if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
402: {
403: if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
404: stream_putl (s, or->cost + or->u.ext.type2_cost);
405: else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
406: stream_putl (s, or->u.ext.type2_cost);
407: else
408: stream_putl (s, or->cost);
409: }
410:
411: stream_putw_at (s, 0, stream_get_endp (s));
412:
413: zclient_send_message(zclient);
414: }
415: }
416:
417: void
418: ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
419: {
420: struct zapi_ipv4 api;
421: struct ospf_path *path;
422: struct in_addr *nexthop;
423: struct listnode *node, *nnode;
424:
425: if (zclient->redist[ZEBRA_ROUTE_OSPF])
426: {
427: api.type = ZEBRA_ROUTE_OSPF;
428: api.flags = 0;
429: api.message = 0;
430: api.ifindex_num = 0;
431: api.nexthop_num = 0;
432:
433: for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
434: {
435: if (path->nexthop.s_addr != INADDR_ANY)
436: {
437: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
438: api.nexthop_num = 1;
439: nexthop = &path->nexthop;
440: api.nexthop = &nexthop;
441: }
442: else if (if_lookup_by_index(path->ifindex))
443: {
444: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
445: api.ifindex_num = 1;
446: api.ifindex = &path->ifindex;
447: }
448: else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
449: {
450: zlog_debug("Zebra: no ifp %s %d",
451: inet_ntoa(p->prefix),
452: p->prefixlen);
453: }
454:
455: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
456:
457: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
458: {
459: char buf[2][INET_ADDRSTRLEN];
460: zlog_debug("Zebra: Route delete %s/%d nexthop %s",
461: inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])),
462: p->prefixlen,
463: inet_ntop(AF_INET, *api.nexthop,
464: buf[1], sizeof(buf[1])));
465: }
466: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
467: {
468: zlog_debug ("Zebra: Route delete %s/%d ifindex %d",
469: inet_ntoa (p->prefix),
470: p->prefixlen, *api.ifindex);
471: }
472: }
473: }
474: }
475:
476: void
477: ospf_zebra_add_discard (struct prefix_ipv4 *p)
478: {
479: struct zapi_ipv4 api;
480:
481: if (zclient->redist[ZEBRA_ROUTE_OSPF])
482: {
483: api.type = ZEBRA_ROUTE_OSPF;
484: api.flags = ZEBRA_FLAG_BLACKHOLE;
485: api.message = 0;
486: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
487: api.nexthop_num = 0;
488: api.ifindex_num = 0;
489:
490: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
491:
492: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
493: zlog_debug ("Zebra: Route add discard %s/%d",
494: inet_ntoa (p->prefix), p->prefixlen);
495: }
496: }
497:
498: void
499: ospf_zebra_delete_discard (struct prefix_ipv4 *p)
500: {
501: struct zapi_ipv4 api;
502:
503: if (zclient->redist[ZEBRA_ROUTE_OSPF])
504: {
505: api.type = ZEBRA_ROUTE_OSPF;
506: api.flags = ZEBRA_FLAG_BLACKHOLE;
507: api.message = 0;
508: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
509: api.nexthop_num = 0;
510: api.ifindex_num = 0;
511:
512: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
513:
514: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
515: zlog_debug ("Zebra: Route delete discard %s/%d",
516: inet_ntoa (p->prefix), p->prefixlen);
517:
518: }
519: }
520:
521: int
522: ospf_is_type_redistributed (int type)
523: {
524: return (DEFAULT_ROUTE_TYPE (type)) ?
525: zclient->default_information : zclient->redist[type];
526: }
527:
528: int
529: ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
530: {
531: int force = 0;
532:
533: if (ospf_is_type_redistributed (type))
534: {
535: if (mtype != ospf->dmetric[type].type)
536: {
537: ospf->dmetric[type].type = mtype;
538: force = LSA_REFRESH_FORCE;
539: }
540: if (mvalue != ospf->dmetric[type].value)
541: {
542: ospf->dmetric[type].value = mvalue;
543: force = LSA_REFRESH_FORCE;
544: }
545:
546: ospf_external_lsa_refresh_type (ospf, type, force);
547:
548: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
549: zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
550: ospf_redist_string(type),
551: metric_type (ospf, type), metric_value (ospf, type));
552:
553: return CMD_SUCCESS;
554: }
555:
556: ospf->dmetric[type].type = mtype;
557: ospf->dmetric[type].value = mvalue;
558:
559: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
560:
561: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
562: zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
563: ospf_redist_string(type),
564: metric_type (ospf, type), metric_value (ospf, type));
565:
566: ospf_asbr_status_update (ospf, ++ospf->redistribute);
567:
568: return CMD_SUCCESS;
569: }
570:
571: int
572: ospf_redistribute_unset (struct ospf *ospf, int type)
573: {
574: if (type == zclient->redist_default)
575: return CMD_SUCCESS;
576:
577: if (!ospf_is_type_redistributed (type))
578: return CMD_SUCCESS;
579:
580: zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
581:
582: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
583: zlog_debug ("Redistribute[%s]: Stop",
584: ospf_redist_string(type));
585:
586: ospf->dmetric[type].type = -1;
587: ospf->dmetric[type].value = -1;
588:
589: /* Remove the routes from OSPF table. */
590: ospf_redistribute_withdraw (ospf, type);
591:
592: ospf_asbr_status_update (ospf, --ospf->redistribute);
593:
594: return CMD_SUCCESS;
595: }
596:
597: int
598: ospf_redistribute_default_set (struct ospf *ospf, int originate,
599: int mtype, int mvalue)
600: {
601: ospf->default_originate = originate;
602: ospf->dmetric[DEFAULT_ROUTE].type = mtype;
603: ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
604:
605: if (ospf_is_type_redistributed (DEFAULT_ROUTE))
606: {
607: /* if ospf->default_originate changes value, is calling
608: ospf_external_lsa_refresh_default sufficient to implement
609: the change? */
610: ospf_external_lsa_refresh_default (ospf);
611:
612: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
613: zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
614: ospf_redist_string(DEFAULT_ROUTE),
615: metric_type (ospf, DEFAULT_ROUTE),
616: metric_value (ospf, DEFAULT_ROUTE));
617: return CMD_SUCCESS;
618: }
619:
620: zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
621:
622: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
623: zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
624: metric_type (ospf, DEFAULT_ROUTE),
625: metric_value (ospf, DEFAULT_ROUTE));
626:
627: if (ospf->router_id.s_addr == 0)
628: ospf->external_origin |= (1 << DEFAULT_ROUTE);
629: else
630: thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
631:
632: ospf_asbr_status_update (ospf, ++ospf->redistribute);
633:
634: return CMD_SUCCESS;
635: }
636:
637: int
638: ospf_redistribute_default_unset (struct ospf *ospf)
639: {
640: if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
641: return CMD_SUCCESS;
642:
643: ospf->default_originate = DEFAULT_ORIGINATE_NONE;
644: ospf->dmetric[DEFAULT_ROUTE].type = -1;
645: ospf->dmetric[DEFAULT_ROUTE].value = -1;
646:
647: zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
648:
649: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
650: zlog_debug ("Redistribute[DEFAULT]: Stop");
651:
652: ospf_asbr_status_update (ospf, --ospf->redistribute);
653:
654: return CMD_SUCCESS;
655: }
656:
657: static int
658: ospf_external_lsa_originate_check (struct ospf *ospf,
659: struct external_info *ei)
660: {
661: /* If prefix is multicast, then do not originate LSA. */
662: if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
663: {
664: zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
665: "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
666: return 0;
667: }
668:
669: /* Take care of default-originate. */
670: if (is_prefix_default (&ei->p))
671: if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
672: {
673: zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
674: "for default");
675: return 0;
676: }
677:
678: return 1;
679: }
680:
681: /* If connected prefix is OSPF enable interface, then do not announce. */
682: int
683: ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
684: {
685: struct listnode *node;
686: struct ospf_interface *oi;
687:
688:
689: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
690: if (prefix_match (oi->address, (struct prefix *) &ei->p))
691: return 0;
692: return 1;
693: }
694:
695: /* return 1 if external LSA must be originated, 0 otherwise */
696: int
697: ospf_redistribute_check (struct ospf *ospf,
698: struct external_info *ei, int *changed)
699: {
700: struct route_map_set_values save_values;
701: struct prefix_ipv4 *p = &ei->p;
702: u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
703:
704: if (changed)
705: *changed = 0;
706:
707: if (!ospf_external_lsa_originate_check (ospf, ei))
708: return 0;
709:
710: /* Take care connected route. */
711: if (type == ZEBRA_ROUTE_CONNECT &&
712: !ospf_distribute_check_connected (ospf, ei))
713: return 0;
714:
715: if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
716: /* distirbute-list exists, but access-list may not? */
717: if (DISTRIBUTE_LIST (ospf, type))
718: if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
719: {
720: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
721: zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
722: ospf_redist_string(type),
723: inet_ntoa (p->prefix), p->prefixlen);
724: return 0;
725: }
726:
727: save_values = ei->route_map_set;
728: ospf_reset_route_map_set_values (&ei->route_map_set);
729:
730: /* apply route-map if needed */
731: if (ROUTEMAP_NAME (ospf, type))
732: {
733: int ret;
734:
735: ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
736: RMAP_OSPF, ei);
737:
738: if (ret == RMAP_DENYMATCH)
739: {
740: ei->route_map_set = save_values;
741: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
742: zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
743: ospf_redist_string(type),
744: inet_ntoa (p->prefix), p->prefixlen);
745: return 0;
746: }
747:
748: /* check if 'route-map set' changed something */
749: if (changed)
750: *changed = !ospf_route_map_set_compare (&ei->route_map_set,
751: &save_values);
752: }
753:
754: return 1;
755: }
756:
757: /* OSPF route-map set for redistribution */
758: void
759: ospf_routemap_set (struct ospf *ospf, int type, const char *name)
760: {
761: if (ROUTEMAP_NAME (ospf, type))
762: free (ROUTEMAP_NAME (ospf, type));
763:
764: ROUTEMAP_NAME (ospf, type) = strdup (name);
765: ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
766: }
767:
768: void
769: ospf_routemap_unset (struct ospf *ospf, int type)
770: {
771: if (ROUTEMAP_NAME (ospf, type))
772: free (ROUTEMAP_NAME (ospf, type));
773:
774: ROUTEMAP_NAME (ospf, type) = NULL;
775: ROUTEMAP (ospf, type) = NULL;
776: }
777:
778: /* Zebra route add and delete treatment. */
779: static int
780: ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
781: zebra_size_t length)
782: {
783: struct stream *s;
784: struct zapi_ipv4 api;
785: unsigned long ifindex;
786: struct in_addr nexthop;
787: struct prefix_ipv4 p;
788: struct external_info *ei;
789: struct ospf *ospf;
790:
791: s = zclient->ibuf;
792: ifindex = 0;
793: nexthop.s_addr = 0;
794:
795: /* Type, flags, message. */
796: api.type = stream_getc (s);
797: api.flags = stream_getc (s);
798: api.message = stream_getc (s);
799:
800: /* IPv4 prefix. */
801: memset (&p, 0, sizeof (struct prefix_ipv4));
802: p.family = AF_INET;
803: p.prefixlen = stream_getc (s);
804: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
805:
806: if (IPV4_NET127(ntohl(p.prefix.s_addr)))
807: return 0;
808:
809: /* Nexthop, ifindex, distance, metric. */
810: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
811: {
812: api.nexthop_num = stream_getc (s);
813: nexthop.s_addr = stream_get_ipv4 (s);
814: }
815: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
816: {
817: api.ifindex_num = stream_getc (s);
818: /* XXX assert(api.ifindex_num == 1); */
819: ifindex = stream_getl (s);
820: }
821: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
822: api.distance = stream_getc (s);
823: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
824: api.metric = stream_getl (s);
825:
826: ospf = ospf_lookup ();
827: if (ospf == NULL)
828: return 0;
829:
830: if (command == ZEBRA_IPV4_ROUTE_ADD)
831: {
832: /* XXX|HACK|TODO|FIXME:
833: * Maybe we should ignore reject/blackhole routes? Testing shows that
834: * there is no problems though and this is only way to "summarize"
835: * routes in ASBR at the moment. Maybe we need just a better generalised
836: * solution for these types?
837: *
838: * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
839: * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
840: * return 0;
841: */
842:
843: ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
844:
845: if (ospf->router_id.s_addr == 0)
846: /* Set flags to generate AS-external-LSA originate event
847: for each redistributed protocols later. */
848: ospf->external_origin |= (1 << api.type);
849: else
850: {
851: if (ei)
852: {
853: if (is_prefix_default (&p))
854: ospf_external_lsa_refresh_default (ospf);
855: else
856: {
857: struct ospf_lsa *current;
858:
859: current = ospf_external_info_find_lsa (ospf, &ei->p);
860: if (!current)
861: ospf_external_lsa_originate (ospf, ei);
862: else if (IS_LSA_MAXAGE (current))
863: ospf_external_lsa_refresh (ospf, current,
864: ei, LSA_REFRESH_FORCE);
865: else
866: zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
867: inet_ntoa (p.prefix));
868: }
869: }
870: }
871: }
872: else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
873: {
874: ospf_external_info_delete (api.type, p);
875: if (is_prefix_default (&p))
876: ospf_external_lsa_refresh_default (ospf);
877: else
878: ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
879: }
880:
881: return 0;
882: }
883:
884:
885: int
886: ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
887: {
888: /* Lookup access-list for distribute-list. */
889: DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
890:
891: /* Clear previous distribute-name. */
892: if (DISTRIBUTE_NAME (ospf, type))
893: free (DISTRIBUTE_NAME (ospf, type));
894:
895: /* Set distribute-name. */
896: DISTRIBUTE_NAME (ospf, type) = strdup (name);
897:
898: /* If access-list have been set, schedule update timer. */
899: if (DISTRIBUTE_LIST (ospf, type))
900: ospf_distribute_list_update (ospf, type);
901:
902: return CMD_SUCCESS;
903: }
904:
905: int
906: ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
907: {
908: /* Schedule update timer. */
909: if (DISTRIBUTE_LIST (ospf, type))
910: ospf_distribute_list_update (ospf, type);
911:
912: /* Unset distribute-list. */
913: DISTRIBUTE_LIST (ospf, type) = NULL;
914:
915: /* Clear distribute-name. */
916: if (DISTRIBUTE_NAME (ospf, type))
917: free (DISTRIBUTE_NAME (ospf, type));
918:
919: DISTRIBUTE_NAME (ospf, type) = NULL;
920:
921: return CMD_SUCCESS;
922: }
923:
924: /* distribute-list update timer. */
925: static int
926: ospf_distribute_list_update_timer (struct thread *thread)
927: {
928: struct route_node *rn;
929: struct external_info *ei;
930: struct route_table *rt;
931: struct ospf_lsa *lsa;
932: int type, default_refresh = 0;
933: struct ospf *ospf;
934:
935: ospf = ospf_lookup ();
936: if (ospf == NULL)
937: return 0;
938:
939: ospf->t_distribute_update = NULL;
940:
941: zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
942:
943: /* foreach all external info. */
944: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
945: {
946: rt = EXTERNAL_INFO (type);
947: if (!rt)
948: continue;
949: for (rn = route_top (rt); rn; rn = route_next (rn))
950: if ((ei = rn->info) != NULL)
951: {
952: if (is_prefix_default (&ei->p))
953: default_refresh = 1;
954: else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
955: ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
956: else
957: ospf_external_lsa_originate (ospf, ei);
958: }
959: }
960: if (default_refresh)
961: ospf_external_lsa_refresh_default (ospf);
962: return 0;
963: }
964:
965: #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
966:
967: /* Update distribute-list and set timer to apply access-list. */
968: void
969: ospf_distribute_list_update (struct ospf *ospf, int type)
970: {
971: struct route_table *rt;
972:
973: /* External info does not exist. */
974: if (!(rt = EXTERNAL_INFO (type)))
975: return;
976:
977: /* If exists previously invoked thread, then let it continue. */
978: if (ospf->t_distribute_update)
979: return;
980:
981: /* Set timer. */
982: ospf->t_distribute_update =
983: thread_add_timer (master, ospf_distribute_list_update_timer,
984: (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
985: }
986:
987: /* If access-list is updated, apply some check. */
988: static void
989: ospf_filter_update (struct access_list *access)
990: {
991: struct ospf *ospf;
992: int type;
993: int abr_inv = 0;
994: struct ospf_area *area;
995: struct listnode *node;
996:
997: /* If OSPF instatnce does not exist, return right now. */
998: ospf = ospf_lookup ();
999: if (ospf == NULL)
1000: return;
1001:
1002: /* Update distribute-list, and apply filter. */
1003: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1004: {
1005: if (ROUTEMAP (ospf, type) != NULL)
1006: {
1007: /* if route-map is not NULL it may be using this access list */
1008: ospf_distribute_list_update (ospf, type);
1009: continue;
1010: }
1011:
1012: /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
1013: * but no distribute list. */
1014: if (type == ZEBRA_ROUTE_MAX)
1015: break;
1016:
1017: if (DISTRIBUTE_NAME (ospf, type))
1018: {
1019: /* Keep old access-list for distribute-list. */
1020: struct access_list *old = DISTRIBUTE_LIST (ospf, type);
1021:
1022: /* Update access-list for distribute-list. */
1023: DISTRIBUTE_LIST (ospf, type) =
1024: access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
1025:
1026: /* No update for this distribute type. */
1027: if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
1028: continue;
1029:
1030: /* Schedule distribute-list update timer. */
1031: if (DISTRIBUTE_LIST (ospf, type) == NULL ||
1032: strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
1033: ospf_distribute_list_update (ospf, type);
1034: }
1035: }
1036:
1037: /* Update Area access-list. */
1038: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1039: {
1040: if (EXPORT_NAME (area))
1041: {
1042: EXPORT_LIST (area) = NULL;
1043: abr_inv++;
1044: }
1045:
1046: if (IMPORT_NAME (area))
1047: {
1048: IMPORT_LIST (area) = NULL;
1049: abr_inv++;
1050: }
1051: }
1052:
1053: /* Schedule ABR tasks -- this will be changed -- takada. */
1054: if (IS_OSPF_ABR (ospf) && abr_inv)
1055: ospf_schedule_abr_task (ospf);
1056: }
1057:
1058: /* If prefix-list is updated, do some updates. */
1059: void
1060: ospf_prefix_list_update (struct prefix_list *plist)
1061: {
1062: struct ospf *ospf;
1063: int type;
1064: int abr_inv = 0;
1065: struct ospf_area *area;
1066: struct listnode *node;
1067:
1068: /* If OSPF instatnce does not exist, return right now. */
1069: ospf = ospf_lookup ();
1070: if (ospf == NULL)
1071: return;
1072:
1073: /* Update all route-maps which are used as redistribution filters.
1074: * They might use prefix-list.
1075: */
1076: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1077: {
1078: if (ROUTEMAP (ospf, type) != NULL)
1079: {
1080: /* If route-map is not NULL it may be using this prefix list */
1081: ospf_distribute_list_update (ospf, type);
1082: continue;
1083: }
1084: }
1085:
1086: /* Update area filter-lists. */
1087: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1088: {
1089: /* Update filter-list in. */
1090: if (PREFIX_NAME_IN (area))
1091: if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
1092: {
1093: PREFIX_LIST_IN (area) =
1094: prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
1095: abr_inv++;
1096: }
1097:
1098: /* Update filter-list out. */
1099: if (PREFIX_NAME_OUT (area))
1100: if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
1101: {
1102: PREFIX_LIST_IN (area) =
1103: prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
1104: abr_inv++;
1105: }
1106: }
1107:
1108: /* Schedule ABR task. */
1109: if (IS_OSPF_ABR (ospf) && abr_inv)
1110: ospf_schedule_abr_task (ospf);
1111: }
1112:
1113: static struct ospf_distance *
1114: ospf_distance_new (void)
1115: {
1116: return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1117: }
1118:
1119: static void
1120: ospf_distance_free (struct ospf_distance *odistance)
1121: {
1122: XFREE (MTYPE_OSPF_DISTANCE, odistance);
1123: }
1124:
1125: int
1126: ospf_distance_set (struct vty *vty, struct ospf *ospf,
1127: const char *distance_str,
1128: const char *ip_str,
1129: const char *access_list_str)
1130: {
1131: int ret;
1132: struct prefix_ipv4 p;
1133: u_char distance;
1134: struct route_node *rn;
1135: struct ospf_distance *odistance;
1136:
1137: ret = str2prefix_ipv4 (ip_str, &p);
1138: if (ret == 0)
1139: {
1140: vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1141: return CMD_WARNING;
1142: }
1143:
1144: distance = atoi (distance_str);
1145:
1146: /* Get OSPF distance node. */
1147: rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
1148: if (rn->info)
1149: {
1150: odistance = rn->info;
1151: route_unlock_node (rn);
1152: }
1153: else
1154: {
1155: odistance = ospf_distance_new ();
1156: rn->info = odistance;
1157: }
1158:
1159: /* Set distance value. */
1160: odistance->distance = distance;
1161:
1162: /* Reset access-list configuration. */
1163: if (odistance->access_list)
1164: {
1165: free (odistance->access_list);
1166: odistance->access_list = NULL;
1167: }
1168: if (access_list_str)
1169: odistance->access_list = strdup (access_list_str);
1170:
1171: return CMD_SUCCESS;
1172: }
1173:
1174: int
1175: ospf_distance_unset (struct vty *vty, struct ospf *ospf,
1176: const char *distance_str,
1177: const char *ip_str, char
1178: const *access_list_str)
1179: {
1180: int ret;
1181: struct prefix_ipv4 p;
1182: u_char distance;
1183: struct route_node *rn;
1184: struct ospf_distance *odistance;
1185:
1186: ret = str2prefix_ipv4 (ip_str, &p);
1187: if (ret == 0)
1188: {
1189: vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1190: return CMD_WARNING;
1191: }
1192:
1193: distance = atoi (distance_str);
1194:
1195: rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
1196: if (!rn)
1197: {
1198: vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1199: return CMD_WARNING;
1200: }
1201:
1202: odistance = rn->info;
1203:
1204: if (odistance->access_list)
1205: free (odistance->access_list);
1206: ospf_distance_free (odistance);
1207:
1208: rn->info = NULL;
1209: route_unlock_node (rn);
1210: route_unlock_node (rn);
1211:
1212: return CMD_SUCCESS;
1213: }
1214:
1215: void
1216: ospf_distance_reset (struct ospf *ospf)
1217: {
1218: struct route_node *rn;
1219: struct ospf_distance *odistance;
1220:
1221: for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
1222: if ((odistance = rn->info) != NULL)
1223: {
1224: if (odistance->access_list)
1225: free (odistance->access_list);
1226: ospf_distance_free (odistance);
1227: rn->info = NULL;
1228: route_unlock_node (rn);
1229: }
1230: }
1231:
1232: u_char
1233: ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1234: {
1235: struct ospf *ospf;
1236:
1237: ospf = ospf_lookup ();
1238: if (ospf == NULL)
1239: return 0;
1240:
1241: if (ospf->distance_intra)
1242: if (or->path_type == OSPF_PATH_INTRA_AREA)
1243: return ospf->distance_intra;
1244:
1245: if (ospf->distance_inter)
1246: if (or->path_type == OSPF_PATH_INTER_AREA)
1247: return ospf->distance_inter;
1248:
1249: if (ospf->distance_external)
1250: if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
1251: || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1252: return ospf->distance_external;
1253:
1254: if (ospf->distance_all)
1255: return ospf->distance_all;
1256:
1257: return 0;
1258: }
1259:
1260: void
1261: ospf_zebra_init ()
1262: {
1263: /* Allocate zebra structure. */
1264: zclient = zclient_new ();
1265: zclient_init (zclient, ZEBRA_ROUTE_OSPF);
1266: zclient->router_id_update = ospf_router_id_update_zebra;
1267: zclient->interface_add = ospf_interface_add;
1268: zclient->interface_delete = ospf_interface_delete;
1269: zclient->interface_up = ospf_interface_state_up;
1270: zclient->interface_down = ospf_interface_state_down;
1271: zclient->interface_address_add = ospf_interface_address_add;
1272: zclient->interface_address_delete = ospf_interface_address_delete;
1273: zclient->ipv4_route_add = ospf_zebra_read_ipv4;
1274: zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
1275:
1276: access_list_add_hook (ospf_filter_update);
1277: access_list_delete_hook (ospf_filter_update);
1278: prefix_list_add_hook (ospf_prefix_list_update);
1279: prefix_list_delete_hook (ospf_prefix_list_update);
1280: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>