mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	Reworked proto lists -- each proto is now in two lists: the global one
(proto_list) and per-type one (original lists). A lot of things simplified. Implemented `disable', `enable' and `restart' CLI commands.
This commit is contained in:
		
							
								
								
									
										4
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								TODO
									
									
									
									
									
								
							| @@ -28,6 +28,7 @@ Core | ||||
| - config: useless rules when protocols disabled | ||||
| - config: remove protocol startup priority hacks? | ||||
| - config: better datetime format | ||||
| - config: avoid upper case in default protocol names | ||||
|  | ||||
| - krt: rescan interfaces when route addition fails? | ||||
| - krt: does PERSIST mode have any sense if kernel syncer is shut down as last? | ||||
| @@ -39,14 +40,11 @@ Core | ||||
|  | ||||
| Commands | ||||
| ~~~~~~~~ | ||||
| shutdown			# order system shutdown | ||||
| configure [<file>] | ||||
| show	<name>			# show everything you know about symbol <name> | ||||
| 	rip ??? [<name>] | ||||
| 	ospf ??? [<name>] | ||||
| 	static ??? [<name>] | ||||
| 	symbols | ||||
| (disable|enable|restart) <protocol>	# or ALL? | ||||
| - showing of routing table as seen by given protocol | ||||
| - showing of deleted routing tables and filters | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,11 @@ Reply codes of BIRD command-line interface | ||||
| 0005	Reconfiguration already in progress, queueing | ||||
| 0006	Reconfiguration ignored, shutting down | ||||
| 0007	Shutdown ordered | ||||
| 0008	Already disabled | ||||
| 0009	Disabled | ||||
| 0010	Already enabled | ||||
| 0011	Enabled | ||||
| 0012	Restarted | ||||
|  | ||||
| 1000	BIRD version | ||||
| 1001	Interface list | ||||
| @@ -31,6 +36,7 @@ Reply codes of BIRD command-line interface | ||||
| 8000	Reply too long | ||||
| 8001	Route not found | ||||
| 8002	Configuration file error | ||||
| 8003	No protocols match | ||||
|  | ||||
| 9000	Command too long | ||||
| 9001	Parse error | ||||
|   | ||||
| @@ -30,6 +30,7 @@ CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIREC | ||||
| %type <s> optsym | ||||
| %type <ra> r_args | ||||
| %type <i> echo_mask echo_size | ||||
| %type <t> proto_patt | ||||
|  | ||||
| CF_GRAMMAR | ||||
|  | ||||
| @@ -287,6 +288,19 @@ echo_size: | ||||
|    } | ||||
|  ; | ||||
|  | ||||
| CF_CLI(DISABLE, proto_patt, <protocol> | <pattern> | all, [[Disable protocol]]) | ||||
| { proto_xxable($2, 0); } ; | ||||
| CF_CLI(ENABLE, proto_patt, <protocol> | <pattern> | all, [[Enable protocol]]) | ||||
| { proto_xxable($2, 1); } ; | ||||
| CF_CLI(RESTART, proto_patt, <protocol> | <pattern> | all, [[Restart protocol]]) | ||||
| { proto_xxable($2, 2); } ; | ||||
|  | ||||
| proto_patt: | ||||
|    SYM { $$ = $1->name; } | ||||
|  | ALL { $$ = "*"; } | ||||
|  | TEXT | ||||
|  ; | ||||
|  | ||||
| CF_CODE | ||||
|  | ||||
| CF_END | ||||
|   | ||||
| @@ -278,7 +278,7 @@ ifa_notify_change(unsigned c, struct ifa *a) | ||||
|   struct proto *p; | ||||
|  | ||||
|   debug("IFA change notification (%x) for %s:%I\n", c, a->iface->name, a->ip); | ||||
|   WALK_LIST(p, proto_list) | ||||
|   WALK_LIST(p, active_proto_list) | ||||
|     if (p->ifa_notify) | ||||
|       p->ifa_notify(p, c, a); | ||||
| } | ||||
| @@ -307,7 +307,7 @@ if_notify_change(unsigned c, struct iface *i) | ||||
| 	ifa_notify_change(IF_CHANGE_DOWN, a); | ||||
|       } | ||||
|  | ||||
|   WALK_LIST(p, proto_list) | ||||
|   WALK_LIST(p, active_proto_list) | ||||
|     if (p->if_notify) | ||||
|       p->if_notify(p, c, i); | ||||
|  | ||||
|   | ||||
							
								
								
									
										89
									
								
								nest/proto.c
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								nest/proto.c
									
									
									
									
									
								
							| @@ -15,6 +15,7 @@ | ||||
| #include "lib/resource.h" | ||||
| #include "lib/lists.h" | ||||
| #include "lib/event.h" | ||||
| #include "lib/string.h" | ||||
| #include "conf/conf.h" | ||||
| #include "nest/route.h" | ||||
| #include "nest/iface.h" | ||||
| @@ -24,8 +25,15 @@ | ||||
| static pool *proto_pool; | ||||
|  | ||||
| list protocol_list; | ||||
| list proto_list; | ||||
| static list proto_list; | ||||
|  | ||||
| #define WALK_PROTO_LIST(p) do {							\ | ||||
| 	node *nn;								\ | ||||
| 	WALK_LIST(nn, proto_list) {						\ | ||||
| 		struct proto *p = SKIP_BACK(struct proto, glob_node, nn); | ||||
| #define WALK_PROTO_LIST_END } } while(0) | ||||
|  | ||||
| list active_proto_list; | ||||
| static list inactive_proto_list; | ||||
| static list initial_proto_list; | ||||
| static list flush_proto_list; | ||||
| @@ -64,7 +72,7 @@ proto_relink(struct proto *p) | ||||
|   switch (p->core_state) | ||||
|     { | ||||
|     case FS_HAPPY: | ||||
|       l = &proto_list; | ||||
|       l = &active_proto_list; | ||||
|       break; | ||||
|     case FS_FLUSHING: | ||||
|       l = &flush_proto_list; | ||||
| @@ -153,6 +161,7 @@ protos_preconfig(struct config *c) | ||||
|   struct protocol *p; | ||||
|  | ||||
|   init_list(&proto_list); | ||||
|   init_list(&active_proto_list); | ||||
|   init_list(&inactive_proto_list); | ||||
|   init_list(&initial_proto_list); | ||||
|   init_list(&flush_proto_list); | ||||
| @@ -194,6 +203,7 @@ proto_init(struct proto_config *c) | ||||
|   q->proto_state = PS_DOWN; | ||||
|   q->core_state = FS_HUNGRY; | ||||
|   proto_enqueue(&initial_proto_list, q); | ||||
|   add_tail(&proto_list, &q->glob_node); | ||||
|   /* | ||||
|    *  HACK ALERT!  In case of multiple kernel routing tables, | ||||
|    *  the kernel syncer acts as multiple protocols which cooperate | ||||
| @@ -282,6 +292,7 @@ proto_rethink_goal(struct proto *p) | ||||
|       DBG("%s has shut down for reconfiguration\n", p->name); | ||||
|       config_del_obstacle(p->cf->global); | ||||
|       rem_node(&p->n); | ||||
|       rem_node(&p->glob_node); | ||||
|       mb_free(p); | ||||
|       if (!nc) | ||||
| 	return; | ||||
| @@ -303,7 +314,7 @@ proto_rethink_goal(struct proto *p) | ||||
|       if (p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN) | ||||
| 	{ | ||||
| 	  DBG("Kicking %s up\n", p->name); | ||||
| 	  ASSERT(q->startup_counter > 0); | ||||
| 	  if (q->startup_counter > 0)	/* FIXME: Kill the startup counter hack! */ | ||||
| 	    q->startup_counter--; | ||||
| 	  proto_init_instance(p); | ||||
| 	  proto_notify_state(p, (q->start ? q->start(p) : PS_UP)); | ||||
| @@ -326,7 +337,7 @@ protos_dump_all(void) | ||||
|  | ||||
|   debug("Protocols:\n"); | ||||
|  | ||||
|   WALK_LIST(p, proto_list) | ||||
|   WALK_LIST(p, active_proto_list) | ||||
|     { | ||||
|       debug("  protocol %s (pri=%d): state %s/%s\n", p->name, p->proto->priority, | ||||
| 	    p_states[p->proto_state], c_states[p->core_state]); | ||||
| @@ -343,6 +354,8 @@ protos_dump_all(void) | ||||
|     debug("  inactive %s: state %s/%s\n", p->name, p_states[p->proto_state], c_states[p->core_state]); | ||||
|   WALK_LIST(p, initial_proto_list) | ||||
|     debug("  initial %s\n", p->name); | ||||
|   WALK_LIST(p, flush_proto_list) | ||||
|     debug("  flushing %s\n", p->name); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -514,15 +527,6 @@ proto_do_show(struct proto *p, int verbose) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| proto_do_show_list(list *l, int verbose) | ||||
| { | ||||
|   struct proto *p; | ||||
|  | ||||
|   WALK_LIST(p, *l) | ||||
|     proto_do_show(p, verbose); | ||||
| } | ||||
|  | ||||
| void | ||||
| proto_show(struct symbol *s, int verbose) | ||||
| { | ||||
| @@ -536,9 +540,9 @@ proto_show(struct symbol *s, int verbose) | ||||
|     proto_do_show(((struct proto_config *)s->def)->proto, verbose); | ||||
|   else | ||||
|     { | ||||
|       proto_do_show_list(&proto_list, verbose); | ||||
|       proto_do_show_list(&flush_proto_list, verbose); | ||||
|       proto_do_show_list(&inactive_proto_list, verbose); | ||||
|       WALK_PROTO_LIST(p) | ||||
| 	proto_do_show(p, verbose); | ||||
|       WALK_PROTO_LIST_END; | ||||
|     } | ||||
|   cli_msg(0, ""); | ||||
| } | ||||
| @@ -559,7 +563,7 @@ proto_get_named(struct symbol *sym, struct protocol *pr) | ||||
|   else | ||||
|     { | ||||
|       p = NULL; | ||||
|       WALK_LIST(q, proto_list) | ||||
|       WALK_LIST(q, active_proto_list) | ||||
| 	if (q->proto == pr) | ||||
| 	  { | ||||
| 	    if (p) | ||||
| @@ -571,3 +575,54 @@ proto_get_named(struct symbol *sym, struct protocol *pr) | ||||
|     } | ||||
|   return p; | ||||
| } | ||||
|  | ||||
| void | ||||
| proto_xxable(char *pattern, int xx) | ||||
| { | ||||
|   int cnt = 0; | ||||
|   WALK_PROTO_LIST(p) | ||||
|     if (patmatch(pattern, p->name)) | ||||
|       { | ||||
| 	cnt++; | ||||
| 	switch (xx) | ||||
| 	  { | ||||
| 	  case 0: | ||||
| 	    if (p->disabled) | ||||
| 	      cli_msg(-8, "%s: already disabled", p->name); | ||||
| 	    else | ||||
| 	      { | ||||
| 		cli_msg(-9, "%s: disabled", p->name); | ||||
| 		p->disabled = 1; | ||||
| 	      } | ||||
| 	    break; | ||||
| 	  case 1: | ||||
| 	    if (!p->disabled) | ||||
| 	      cli_msg(-10, "%s: already enabled", p->name); | ||||
| 	    else | ||||
| 	      { | ||||
| 		cli_msg(-11, "%s: enabled", p->name); | ||||
| 		p->disabled = 0; | ||||
| 	      } | ||||
| 	    break; | ||||
| 	  case 2: | ||||
| 	    if (p->disabled) | ||||
| 	      cli_msg(-8, "%s: already disabled", p->name); | ||||
| 	    else | ||||
| 	      { | ||||
| 		p->disabled = 1; | ||||
| 		proto_rethink_goal(p); | ||||
| 		p->disabled = 0; | ||||
| 		cli_msg(-12, "%s: restarted", p->name); | ||||
| 	      } | ||||
| 	    break; | ||||
| 	  default: | ||||
| 	    ASSERT(0); | ||||
| 	  } | ||||
| 	proto_rethink_goal(p); | ||||
|       } | ||||
|   WALK_PROTO_LIST_END; | ||||
|   if (!cnt) | ||||
|     cli_msg(8003, "No protocols match"); | ||||
|   else | ||||
|     cli_msg(0, ""); | ||||
| } | ||||
|   | ||||
| @@ -87,7 +87,8 @@ struct proto_config { | ||||
| }; | ||||
|  | ||||
| struct proto { | ||||
|   node n; | ||||
|   node n;				/* Node in *_proto_list */ | ||||
|   node glob_node;			/* Node in global proto_list */ | ||||
|   struct protocol *proto;		/* Protocol */ | ||||
|   struct proto_config *cf;		/* Configuration data */ | ||||
|   struct proto_config *cf_new;		/* Configuration we want to switch to after shutdown (NULL=delete) */ | ||||
| @@ -151,10 +152,12 @@ struct proto { | ||||
| void proto_build(struct proto_config *); | ||||
| void *proto_new(struct proto_config *, unsigned size); | ||||
| void *proto_config_new(struct protocol *, unsigned size); | ||||
|  | ||||
| void proto_show(struct symbol *, int); | ||||
| struct proto *proto_get_named(struct symbol *, struct protocol *); | ||||
| void proto_xxable(char *, int); | ||||
|  | ||||
| extern list proto_list; | ||||
| extern list active_proto_list; | ||||
|  | ||||
| /* | ||||
|  *  Each protocol instance runs two different state machines: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user