Revision bf47fe4b

View differences:

doc/bird.sgml
482 482
	number of networks, number of routes before and after filtering). If
483 483
	you use <cf/count/ instead, only the statistics will be printed.
484 484

  
485
	<tag>enable|disable|restart <m/name/|"<m/pattern/"|all</tag>
486
	Enable, disable or restart a given protocol instance, instances matching the <cf><m/pattern/</cf> or <cf/all/ instances.
487

  
488 485
	<tag>configure [soft] ["<m/config file/"]</tag>
489 486
	Reload configuration from a given file. BIRD will smoothly
490 487
	switch itself to the new configuration, protocols are
......
496 493
	but new routes would be processed according to the new
497 494
	filters.
498 495

  
496
	<tag>enable|disable|restart <m/name/|"<m/pattern/"|all</tag>
497
	Enable, disable or restart a given protocol instance, instances matching the <cf><m/pattern/</cf> or <cf/all/ instances.
498

  
499 499
	<tag/down/
500 500
	Shut BIRD down.
501 501

  
......
944 944
	attributes to be transparent (for example does not prepend its AS number to
945 945
	AS PATH attribute and keep MED attribute). Default: disabled.
946 946

  
947
	<tag>enable route refresh <m/switch/</tag> When BGP speaker
948
	changes its import filter, it has to re-examine all routes
949
	received from its neighbor against the new filter. As these
950
	routes might not be available, there is a BGP protocol
951
	extension Route Refresh (specified in RFC 2918) that allows
952
	BGP speaker to request re-advertisment of all routes from its
953
	neighbor. This option specifies whether BIRD advertises this
954
	capability and accepts such requests. Even when disabled, BIRD
955
	can send route refresh requests. Default: on.
956

  
947 957
	<tag>enable as4 <m/switch/</tag> BGP protocol was designed to use 2B AS numbers
948 958
	and was extended later to allow 4B AS number. BIRD supports 4B AS extension,
949 959
	but by disabling this option it can be persuaded not to advertise it and
nest/config.Y
45 45
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
46 46
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
47 47
CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
48
CF_KEYWORDS(RELOAD, REFEED)
48 49

  
49 50
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
50 51
	RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
......
442 443
{ proto_xxable($2, 1); } ;
443 444
CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
444 445
{ proto_xxable($2, 2); } ;
446
CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
447
{ proto_xxable($2, 3); } ;
448
CF_CLI(REFEED, proto_patt, <protocol> | \"<pattern>\" | all, [[Refeed protocol BROKEN]])
449
{ proto_xxable($2, 4); } ;
450

  
451

  
445 452

  
446 453
CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging]])
447 454
CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | events | packets }), [[Control protocol debugging]])
nest/proto.c
73 73
  rem_node(&p->n);
74 74
  switch (p->core_state)
75 75
    {
76
    case FS_HUNGRY:
77
      l = &inactive_proto_list;
78
      break;
79
    case FS_FEEDING:
76 80
    case FS_HAPPY:
77 81
      l = &active_proto_list;
78 82
      break;
......
80 84
      l = &flush_proto_list;
81 85
      break;
82 86
    default:
83
      l = &inactive_proto_list;
87
      ASSERT(0);
84 88
    }
85 89
  proto_enqueue(l, p);
86 90
}
......
549 553
}
550 554

  
551 555
static void
552
proto_feed(void *P)
556
proto_feed_initial(void *P)
553 557
{
554 558
  struct proto *p = P;
555 559

  
......
577 581
}
578 582

  
579 583
static void
580
proto_schedule_feed(struct proto *p)
584
proto_schedule_feed(struct proto *p, int initial)
581 585
{
582 586
  DBG("%s: Scheduling meal\n", p->name);
583 587
  p->core_state = FS_FEEDING;
584 588
  proto_relink(p);
585
  p->attn->hook = proto_feed;
589
  p->attn->hook = initial ? proto_feed_initial : proto_feed_more;
586 590
  ev_schedule(p->attn);
587 591
}
588 592

  
589 593
/**
594
 * proto_request_feeding - request feeding routes to the protocol
595
 * @p: given protocol 
596
 *
597
 * Sometimes it is needed to send again all routes to the
598
 * protocol. This is called feeding and can be requested by this
599
 * function. This would cause protocol core state transition
600
 * to FS_FEEDING (during feeding) and when completed, it will
601
 * switch back to FS_HAPPY. This function can be called even
602
 * when feeding is already running, in that case it is restarted.
603
 */
604
void
605
proto_request_feeding(struct proto *p)
606
{
607
  ASSERT(p->proto_state == PS_UP);
608

  
609
  /* If we are already feeding, we want to restart it */
610
  if (p->core_state == FS_FEEDING)
611
    {
612
      /* Unless feeding is in initial state */
613
      if (p->attn->hook == proto_feed_initial)
614
	return;
615

  
616
      rt_feed_baby_abort(p);
617
    }
618

  
619
  proto_schedule_feed(p, 0);
620
}
621

  
622
/**
590 623
 * proto_notify_state - notify core about protocol state change
591 624
 * @p: protocol the state of which has changed
592 625
 * @ps: the new status
......
635 668
    case PS_UP:
636 669
      ASSERT(ops == PS_DOWN || ops == PS_START);
637 670
      ASSERT(cs == FS_HUNGRY);
638
      proto_schedule_feed(p);
671
      proto_schedule_feed(p, 1);
639 672
      break;
640 673
    case PS_STOP:
641 674
      if ((cs = FS_FEEDING) || (cs == FS_HAPPY))
......
798 831
	      {
799 832
		cli_msg(-9, "%s: disabled", p->name);
800 833
		p->disabled = 1;
834
		proto_rethink_goal(p);
801 835
	      }
802 836
	    break;
803 837
	  case 1:
......
807 841
	      {
808 842
		cli_msg(-11, "%s: enabled", p->name);
809 843
		p->disabled = 0;
844
		proto_rethink_goal(p);
810 845
	      }
811 846
	    break;
812 847
	  case 2:
......
817 852
		p->disabled = 1;
818 853
		proto_rethink_goal(p);
819 854
		p->disabled = 0;
855
		proto_rethink_goal(p);
820 856
		cli_msg(-12, "%s: restarted", p->name);
821 857
	      }
822 858
	    break;
859
	  case 3:
860
	    // FIXME change msg number
861
	    if (p->disabled)
862
	      cli_msg(-8, "%s: already disabled", p->name);
863
	    else if (p->reload_routes && p->reload_routes(p))
864
	      cli_msg(-12, "%s: reloading", p->name);
865
	    else
866
	      cli_msg(-12, "%s: reload failed", p->name);
867
	    break;
868
	  case 4:
869
	    // FIXME change msg number
870
	    if (p->disabled)
871
	      cli_msg(-8, "%s: already disabled", p->name);
872
	    else
873
	      {
874
		proto_request_feeding(p);
875
		cli_msg(-12, "%s: reexport failed", p->name);
876
	      }
877
	    break;
878

  
823 879
	  default:
824 880
	    ASSERT(0);
825 881
	  }
826
	proto_rethink_goal(p);
827 882
      }
828 883
  WALK_PROTO_LIST_END;
829 884
  if (!cnt)
nest/protocol.h
152 152
   *			It can construct a new rte, add private attributes and
153 153
   *			decide whether the route shall be imported: 1=yes, -1=no,
154 154
   *			0=process it through the import filter set by the user.
155
   *	   reload_routes   Request protocol to reload all its routes to the core
156
   *			(using rte_update()). Returns: 0=reload cannot be done,
157
   *			1= reload is scheduled and will happen (asynchronously).
155 158
   */
156 159

  
157 160
  void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
......
161 164
  struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
162 165
  void (*store_tmp_attrs)(struct rte *rt, struct ea_list *attrs);
163 166
  int (*import_control)(struct proto *, struct rte **rt, struct ea_list **attrs, struct linpool *pool);
167
  int (*reload_routes)(struct proto *);
164 168

  
165 169
  /*
166 170
   *	Routing entry hooks (called only for rte's belonging to this protocol):
......
190 194
void *proto_new(struct proto_config *, unsigned size);
191 195
void *proto_config_new(struct protocol *, unsigned size);
192 196

  
197
void proto_request_feeding(struct proto *p);
193 198
void proto_show(struct symbol *, int);
194 199
struct proto *proto_get_named(struct symbol *, struct protocol *);
195 200
void proto_xxable(char *, int);
......
271 276
 *		HUNGRY/DOWN --> HUNGRY/START --> HUNGRY/UP -->
272 277
 *		FEEDING/UP --> HAPPY/UP --> FLUSHING/STOP|DOWN -->
273 278
 *		HUNGRY/STOP|DOWN --> HUNGRY/DOWN
279
 *
280
 *	Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP 
281
 *	if it wants to refeed the routes (for example BGP does so
282
 *	as a result of received ROUTE-REFRESH request).
274 283
 */
275 284

  
276 285
#define FS_HUNGRY 0
nest/rt-table.c
199 199
  else
200 200
    p->stats.exp_withdraws_received++;
201 201

  
202
  /* This is a tricky part - we don't know whether route 'old' was
203
     exported to protocol 'p' or was filtered by the export filter.
204
     We try tu run the export filter to know this to have a correct
205
     value in 'old' argument of rt_update (and proper filter value)
206

  
207
     FIXME - this is broken because 'configure soft' may change
208
     filters but keep routes */
209

  
202 210
  if (old)
203 211
    {
204 212
      if (p->out_filter == FILTER_REJECT)
......
216 224
	}
217 225
    }
218 226

  
227
  /* FIXME - This is broken because of incorrect 'old' value (see above) */
219 228
  if (!new && !old)
220 229
    return;
221 230

  
......
1122 1131
	    ok = 0;
1123 1132
	  else if (!ic && d->export_mode > 1)
1124 1133
	    {
1134
	      /* FIXME - this shows what should be exported according
1135
		 to current filters, but not what was really exported.
1136
		 'configure soft' command may change the export filter
1137
		 and do not update routes */
1138

  
1125 1139
	      if (p1->out_filter == FILTER_REJECT ||
1126 1140
		  p1->out_filter && f_run(p1->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)
1127 1141
		ok = 0;
proto/bgp/bgp.c
676 676
    }
677 677
}
678 678

  
679
static int
680
bgp_reload_routes(struct proto *P)
681
{
682
  struct bgp_proto *p = (struct bgp_proto *) P;
683
  if (!p->conn || !p->conn->peer_refresh_support)
684
    return 0;
685

  
686
  bgp_schedule_packet(p->conn, PKT_ROUTE_REFRESH);
687
  return 1;
688
}
689

  
679 690
static void
680 691
bgp_start_locked(struct object_lock *lock)
681 692
{
......
792 803
  P->rte_better = bgp_rte_better;
793 804
  P->import_control = bgp_import_control;
794 805
  P->neigh_notify = bgp_neigh_notify;
806
  P->reload_routes = bgp_reload_routes;
795 807
  p->cf = c;
796 808
  p->local_as = c->local_as;
797 809
  p->remote_as = c->remote_as;
proto/bgp/bgp.h
29 29
  u32 default_local_pref;		/* Default value for LOCAL_PREF attribute */
30 30
  u32 default_med;			/* Default value for MULTI_EXIT_DISC attribute */
31 31
  int capabilities;			/* Enable capability handshake [RFC3392] */
32
  int enable_refresh;			/* Enable local support for route refresh [RFC2918] */
32 33
  int enable_as4;			/* Enable local support for 4B AS numbers [RFC4893] */
33 34
  u32 rr_cluster_id;			/* Route reflector cluster ID, if different from local ID */
34 35
  int rr_client;			/* Whether neighbor is RR client of me */
......
66 67
  int start_state;			/* protocol start_state snapshot when connection established */
67 68
  int want_as4_support;			/* Connection tries to establish AS4 session */
68 69
  int peer_as4_support;			/* Peer supports 4B AS numbers [RFC4893] */
70
  int peer_refresh_support;		/* Peer supports route refresh [RFC2918] */
69 71
  unsigned hold_time, keepalive_time;	/* Times calculated from my and neighbor's requirements */
70 72
};
71 73

  
......
202 204
#define PKT_UPDATE		0x02
203 205
#define PKT_NOTIFICATION	0x03
204 206
#define PKT_KEEPALIVE		0x04
207
#define PKT_ROUTE_REFRESH	0x05
205 208
#define PKT_SCHEDULE_CLOSE	0x1f	/* Used internally to schedule socket close */
206 209

  
207 210
/* Attributes */
proto/bgp/config.Y
23 23
	BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
24 24
	PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
25 25
	CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER, MISSING, LLADDR,
26
	DROP, IGNORE)
26
	DROP, IGNORE, ROUTE, REFRESH)
27 27

  
28 28
CF_GRAMMAR
29 29

  
......
40 40
     BGP_CFG->error_amnesia_time = 300;
41 41
     BGP_CFG->error_delay_time_min = 60;
42 42
     BGP_CFG->error_delay_time_max = 300;
43
     BGP_CFG->enable_refresh = 1;
43 44
     BGP_CFG->enable_as4 = bgp_as4_support;
44 45
     BGP_CFG->capabilities = 2;
45 46
     BGP_CFG->advertise_ipv4 = 1;
......
77 78
 | bgp_proto ERROR FORGET TIME expr ';' { BGP_CFG->error_amnesia_time = $5; } 
78 79
 | bgp_proto ERROR WAIT TIME expr ',' expr ';' { BGP_CFG->error_delay_time_min = $5; BGP_CFG->error_delay_time_max = $7; }
79 80
 | bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; }
81
 | bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; }
80 82
 | bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; }
81 83
 | bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
82 84
 | bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
proto/bgp/packets.c
64 64
#endif
65 65

  
66 66
static byte *
67
bgp_put_cap_rr(struct bgp_conn *conn UNUSED, byte *buf)
68
{
69
  *buf++ = 2;		/* Capability 2: Support for route refresh */
70
  *buf++ = 0;		/* Capability data length */
71
  return buf;
72
}
73

  
74
static byte *
67 75
bgp_put_cap_as4(struct bgp_conn *conn, byte *buf)
68 76
{
69 77
  *buf++ = 65;		/* Capability 65: Support for 4-octet AS number */
......
105 113
  cap = bgp_put_cap_ipv6(conn, cap);
106 114
#endif
107 115

  
116
  if (p->cf->enable_refresh)
117
    cap = bgp_put_cap_rr(conn, cap);
118

  
108 119
  if (conn->want_as4_support)
109 120
    cap = bgp_put_cap_as4(conn, cap);
110 121

  
......
386 397

  
387 398
#endif
388 399

  
400
static byte *
401
bgp_create_route_refresh(struct bgp_conn *conn, byte *buf)
402
{
403
  struct bgp_proto *p = conn->bgp;
404
  BGP_TRACE(D_PACKETS, "Sending ROUTE-REFRESH");
405

  
406
#ifdef IPV6
407
  *buf++ = 0;		/* AFI IPv6 */
408
  *buf++ = BGP_AF_IPV6;
409
#else
410
  *buf++ = 0;		/* AFI IPv4 */
411
  *buf++ = BGP_AF_IPV4;
412
#endif
413
  *buf++ = 0;		/* RFU */
414
  *buf++ = 1;		/* and SAFI 1 */
415
  return buf;
416
}
417

  
389 418
static void
390 419
bgp_create_header(byte *buf, unsigned int len, unsigned int type)
391 420
{
......
447 476
      type = PKT_OPEN;
448 477
      end = bgp_create_open(conn, pkt);
449 478
    }
479
  else if (s & (1 << PKT_ROUTE_REFRESH))
480
    {
481
      s &= ~(1 << PKT_ROUTE_REFRESH);
482
      type = PKT_ROUTE_REFRESH;
483
      end = bgp_create_route_refresh(conn, pkt);
484
    }
450 485
  else if (s & (1 << PKT_UPDATE))
451 486
    {
452 487
      end = bgp_create_update(conn, pkt);
......
517 552

  
518 553
      switch (opt[0])
519 554
	{
555
	case 2:
556
	  if (cl != 0)
557
	    goto err;
558
	  conn->peer_refresh_support = 1;
559
	  break;
520 560
	case 65:
521 561
	  if (cl != 4)
522 562
	    goto err;
......
1084 1124
    }
1085 1125
}
1086 1126

  
1127
static void
1128
bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, int len)
1129
{
1130
  struct bgp_proto *p = conn->bgp;
1131

  
1132
  BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
1133

  
1134
  if (conn->state != BS_ESTABLISHED)
1135
    { bgp_error(conn, 5, 0, NULL, 0); return; }
1136

  
1137
  if (!p->cf->enable_refresh)
1138
    { bgp_error(conn, 1, 3, pkt+18, 1); return; }
1139

  
1140
  if (len != (BGP_HEADER_LENGTH + 4))
1141
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
1142

  
1143
  /* FIXME - we ignore AFI/SAFI values, as we support
1144
     just one value and even an error code for an invalid
1145
     request is not defined */
1146

  
1147
  proto_request_feeding(&p->p);
1148
}
1149

  
1150

  
1087 1151
/**
1088 1152
 * bgp_rx_packet - handle a received packet
1089 1153
 * @conn: BGP connection
......
1103 1167
    case PKT_UPDATE:		return bgp_rx_update(conn, pkt, len);
1104 1168
    case PKT_NOTIFICATION:      return bgp_rx_notification(conn, pkt, len);
1105 1169
    case PKT_KEEPALIVE:		return bgp_rx_keepalive(conn);
1170
    case PKT_ROUTE_REFRESH:	return bgp_rx_route_refresh(conn, pkt, len);
1106 1171
    default:			bgp_error(conn, 1, 3, pkt+18, 1);
1107 1172
    }
1108 1173
}

Also available in: Unified diff