| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *	BIRD -- Direct Device Routes | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2000-01-16 16:40:57 +00:00
										 |  |  |  *	(c) 1998--2000 Martin Mares <mj@ucw.cz> | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *	Can be freely distributed and used under the terms of the GNU GPL. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-04 16:16:08 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DOC: Direct | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2000-06-07 12:29:08 +00:00
										 |  |  |  * The Direct protocol works by converting all ifa_notify() events it receives | 
					
						
							| 
									
										
										
										
											2000-06-04 16:16:08 +00:00
										 |  |  |  * to rte_update() calls for the corresponding network. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-12 21:01:38 +00:00
										 |  |  | #undef LOCAL_DEBUG
 | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "nest/bird.h"
 | 
					
						
							|  |  |  | #include "nest/iface.h"
 | 
					
						
							|  |  |  | #include "nest/protocol.h"
 | 
					
						
							|  |  |  | #include "nest/route.h"
 | 
					
						
							| 
									
										
										
										
											1998-11-29 22:03:58 +00:00
										 |  |  | #include "nest/rt-dev.h"
 | 
					
						
							|  |  |  | #include "conf/conf.h"
 | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | #include "lib/resource.h"
 | 
					
						
							| 
									
										
										
										
											2000-03-31 23:30:21 +00:00
										 |  |  | #include "lib/string.h"
 | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											1999-05-06 21:38:11 +00:00
										 |  |  | dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad) | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1999-02-05 21:37:34 +00:00
										 |  |  |   struct rt_dev_config *P = (void *) p->cf; | 
					
						
							| 
									
										
										
										
											1998-11-29 22:03:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-08-03 19:30:49 +00:00
										 |  |  |   if (!EMPTY_LIST(P->iface_list) && | 
					
						
							| 
									
										
										
										
											2010-03-14 16:36:59 +01:00
										 |  |  |       !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr)) | 
					
						
							| 
									
										
										
										
											1999-08-03 19:30:49 +00:00
										 |  |  |     /* Empty list is automagically treated as "*" */ | 
					
						
							| 
									
										
										
										
											1998-11-29 22:03:58 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2010-02-26 10:55:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (ad->scope <= SCOPE_LINK) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |   if (c & IF_CHANGE_DOWN) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       net *n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-05-06 21:38:11 +00:00
										 |  |  |       DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip); | 
					
						
							|  |  |  |       n = net_find(p->table, ad->prefix, ad->pxlen); | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       if (!n) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2000-03-12 21:01:38 +00:00
										 |  |  | 	  DBG("dev_if_notify: device shutdown: prefix not found\n"); | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  | 	  return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-01 14:07:13 +02:00
										 |  |  |       rte_update(p->table, n, p, p, NULL); | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   else if (c & IF_CHANGE_UP) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       rta *a, A; | 
					
						
							|  |  |  |       net *n; | 
					
						
							|  |  |  |       rte *e; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-12 21:01:38 +00:00
										 |  |  |       DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip); | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       bzero(&A, sizeof(A)); | 
					
						
							| 
									
										
										
										
											1998-10-18 11:50:36 +00:00
										 |  |  |       A.proto = p; | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       A.source = RTS_DEVICE; | 
					
						
							| 
									
										
										
										
											2010-02-26 10:55:58 +01:00
										 |  |  |       A.scope = SCOPE_UNIVERSE; | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       A.cast = RTC_UNICAST; | 
					
						
							|  |  |  |       A.dest = RTD_DEVICE; | 
					
						
							| 
									
										
										
										
											1999-05-06 21:38:11 +00:00
										 |  |  |       A.iface = ad->iface; | 
					
						
							| 
									
										
										
										
											1999-11-04 13:29:43 +00:00
										 |  |  |       A.eattrs = NULL; | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       a = rta_lookup(&A); | 
					
						
							| 
									
										
										
										
											2000-02-29 23:19:52 +00:00
										 |  |  |       n = net_get(p->table, ad->prefix, ad->pxlen); | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       e = rte_get_temp(a); | 
					
						
							| 
									
										
										
										
											1998-10-20 15:13:18 +00:00
										 |  |  |       e->net = n; | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |       e->pflags = 0; | 
					
						
							| 
									
										
										
										
											2009-06-01 14:07:13 +02:00
										 |  |  |       rte_update(p->table, n, p, p, e); | 
					
						
							| 
									
										
										
										
											1998-06-04 20:28:43 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-02-05 21:37:34 +00:00
										 |  |  | static struct proto * | 
					
						
							|  |  |  | dev_init(struct proto_config *c) | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1999-02-05 21:37:34 +00:00
										 |  |  |   struct proto *p = proto_new(c, sizeof(struct proto)); | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-05-06 21:38:11 +00:00
										 |  |  |   p->ifa_notify = dev_ifa_notify; | 
					
						
							| 
									
										
										
										
											1999-02-05 21:37:34 +00:00
										 |  |  |   return p; | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-01-17 00:20:17 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | dev_reconfigure(struct proto *p, struct proto_config *new) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct rt_dev_config *o = (struct rt_dev_config *) p->cf; | 
					
						
							|  |  |  |   struct rt_dev_config *n = (struct rt_dev_config *) new; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   return iface_patts_equal(&o->iface_list, &n->iface_list, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | struct protocol proto_device = { | 
					
						
							| 
									
										
										
										
											1999-03-26 21:44:38 +00:00
										 |  |  |   name:		"Direct", | 
					
						
							| 
									
										
										
										
											2000-01-17 11:52:50 +00:00
										 |  |  |   template:	"direct%d", | 
					
						
							| 
									
										
										
										
											1999-02-05 21:37:34 +00:00
										 |  |  |   init:		dev_init, | 
					
						
							| 
									
										
										
										
											2000-01-17 00:20:17 +00:00
										 |  |  |   reconfigure:	dev_reconfigure | 
					
						
							| 
									
										
										
										
											1998-06-03 08:42:16 +00:00
										 |  |  | }; |