}
}
+static int
+bgp_maxmed_onstartup_applicable (struct bgp *bgp)
+{
+ if (!bgp->maxmed_onstartup_over)
+ return 1;
+
+ return 0;
+}
+
+int
+bgp_maxmed_onstartup_configured (struct bgp *bgp)
+{
+ if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
+ return 1;
+
+ return 0;
+}
+
+int
+bgp_maxmed_onstartup_active (struct bgp *bgp)
+{
+ if (bgp->t_maxmed_onstartup)
+ return 1;
+
+ return 0;
+}
+
+void
+bgp_maxmed_update (struct bgp *bgp)
+{
+ struct listnode *node, *nnode;
+ struct peer *peer;
+ u_char maxmed_active;
+ u_int32_t maxmed_value;
+
+ if (bgp->v_maxmed_admin)
+ {
+ maxmed_active = 1;
+ maxmed_value = bgp->maxmed_admin_value;
+ }
+ else if (bgp->t_maxmed_onstartup)
+ {
+ maxmed_active = 1;
+ maxmed_value = bgp->maxmed_onstartup_value;
+ }
+ else
+ {
+ maxmed_active = 0;
+ maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
+ }
+
+ if (bgp->maxmed_active != maxmed_active ||
+ bgp->maxmed_value != maxmed_value)
+ {
+ bgp->maxmed_active = maxmed_active;
+ bgp->maxmed_value = maxmed_value;
+
+ for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+ bgp_announce_route_all (peer);
+ }
+}
+
+/* The maxmed onstartup timer expiry callback. */
+static int
+bgp_maxmed_onstartup_timer (struct thread *thread)
+{
+ struct bgp *bgp;
+
+ zlog_info ("Max med on startup ended - timer expired.");
+
+ bgp = THREAD_ARG (thread);
+ THREAD_TIMER_OFF (bgp->t_maxmed_onstartup);
+ bgp->maxmed_onstartup_over = 1;
+
+ bgp_maxmed_update(bgp);
+
+ return 0;
+}
+
+static void
+bgp_maxmed_onstartup_begin (struct bgp *bgp)
+{
+ /* Applicable only once in the process lifetime on the startup */
+ if (bgp->maxmed_onstartup_over)
+ return;
+
+ zlog_info ("Begin maxmed onstartup mode - timer %d seconds",
+ bgp->v_maxmed_onstartup);
+
+ THREAD_TIMER_ON (master, bgp->t_maxmed_onstartup,
+ bgp_maxmed_onstartup_timer,
+ bgp, bgp->v_maxmed_onstartup);
+
+ if (!bgp->v_maxmed_admin)
+ {
+ bgp->maxmed_active = 1;
+ bgp->maxmed_value = bgp->maxmed_onstartup_value;
+ }
+
+ /* Route announce to all peers should happen after this in bgp_establish() */
+}
+
+static void
+bgp_maxmed_onstartup_process_status_change(struct peer *peer)
+{
+ if (peer->status == Established && !peer->bgp->established)
+ {
+ bgp_maxmed_onstartup_begin(peer->bgp);
+ }
+}
+
/* The update delay timer expiry callback. */
static int
bgp_update_delay_timer (struct thread *thread)
if (status == Established)
UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
+ /* If max-med processing is applicable, do the necessary. */
+ if (status == Established)
+ {
+ if (bgp_maxmed_onstartup_configured(peer->bgp) &&
+ bgp_maxmed_onstartup_applicable(peer->bgp))
+ bgp_maxmed_onstartup_process_status_change(peer);
+ else
+ peer->bgp->maxmed_onstartup_over = 1;
+ }
+
/* If update-delay processing is applicable, do the necessary. */
if (bgp_update_delay_configured(peer->bgp) &&
bgp_update_delay_applicable(peer->bgp))
return CMD_SUCCESS;
}
+DEFUN (bgp_maxmed_admin,
+ bgp_maxmed_admin_cmd,
+ "bgp max-med administrative ",
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Administratively applied, for an indefinite period\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ bgp->v_maxmed_admin = 1;
+ bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT;
+
+ bgp_maxmed_update(bgp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (bgp_maxmed_admin_medv,
+ bgp_maxmed_admin_medv_cmd,
+ "bgp max-med administrative <0-4294967294>",
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Administratively applied, for an indefinite period\n"
+ "Max MED value to be used\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ bgp->v_maxmed_admin = 1;
+ VTY_GET_INTEGER ("max-med admin med-value", bgp->maxmed_admin_value, argv[0]);
+
+ bgp_maxmed_update(bgp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_maxmed_admin,
+ no_bgp_maxmed_admin_cmd,
+ "no bgp max-med administrative",
+ NO_STR
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Administratively applied, for an indefinite period\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ bgp->v_maxmed_admin = BGP_MAXMED_ADMIN_UNCONFIGURED;
+ bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT;
+
+ bgp_maxmed_update(bgp);
+
+ return CMD_SUCCESS;
+}
+
+ALIAS (no_bgp_maxmed_admin,
+ no_bgp_maxmed_admin_medv_cmd,
+ "no bgp max-med administrative <0-4294967294>",
+ NO_STR
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Administratively applied, for an indefinite period\n"
+ "Max MED value to be used\n")
+
+
+DEFUN (bgp_maxmed_onstartup,
+ bgp_maxmed_onstartup_cmd,
+ "bgp max-med on-startup <5-86400>",
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Effective on a startup\n"
+ "Time (seconds) period for max-med\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ if (argc != 1)
+ {
+ vty_out (vty, "%% Must supply max-med on-startup period");
+ return CMD_WARNING;
+ }
+
+ VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[0]);
+ bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT;
+
+ bgp_maxmed_update(bgp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (bgp_maxmed_onstartup_medv,
+ bgp_maxmed_onstartup_medv_cmd,
+ "bgp max-med on-startup <5-86400> <0-4294967294>",
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Effective on a startup\n"
+ "Time (seconds) period for max-med\n"
+ "Max MED value to be used\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ if (argc != 2)
+ {
+ vty_out (vty, "%% Must supply max-med on-startup period and med value");
+ return CMD_WARNING;
+ }
+
+ VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[0]);
+ VTY_GET_INTEGER ("max-med on-startup med-value", bgp->maxmed_onstartup_value, argv[1]);
+
+ bgp_maxmed_update(bgp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_maxmed_onstartup,
+ no_bgp_maxmed_onstartup_cmd,
+ "no bgp max-med on-startup",
+ NO_STR
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Effective on a startup\n")
+{
+ struct bgp *bgp;
+
+ bgp = vty->index;
+
+ /* Cancel max-med onstartup if its on */
+ if (bgp->t_maxmed_onstartup)
+ {
+ THREAD_TIMER_OFF (bgp->t_maxmed_onstartup);
+ bgp->maxmed_onstartup_over = 1;
+ }
+
+ bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED;
+ bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT;
+
+ bgp_maxmed_update(bgp);
+
+ return CMD_SUCCESS;
+}
+
+ALIAS (no_bgp_maxmed_onstartup,
+ no_bgp_maxmed_onstartup_period_cmd,
+ "no bgp max-med on-startup <5-86400>",
+ NO_STR
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Effective on a startup\n"
+ "Time (seconds) period for max-med\n")
+
+ALIAS (no_bgp_maxmed_onstartup,
+ no_bgp_maxmed_onstartup_period_medv_cmd,
+ "no bgp max-med on-startup <5-86400> <0-4294967294>",
+ NO_STR
+ BGP_STR
+ "Advertise routes with max-med\n"
+ "Effective on a startup\n"
+ "Time (seconds) period for max-med\n"
+ "Max MED value to be used\n")
+
static int
bgp_update_delay_config_vty (struct vty *vty, const char *delay,
const char *wait)
}
}
+ if (bgp_maxmed_onstartup_configured(bgp) && bgp->maxmed_active)
+ vty_out (vty, "Max-med on-startup active%s", VTY_NEWLINE);
+ if (bgp->v_maxmed_admin)
+ vty_out (vty, "Max-med administrative active%s", VTY_NEWLINE);
+
ents = bgp_table_count (bgp->rib[afi][safi]);
vty_out (vty, "RIB entries %ld, using %s of memory%s", ents,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
install_element (BGP_NODE, &bgp_confederation_peers_cmd);
install_element (BGP_NODE, &no_bgp_confederation_peers_cmd);
+ /* bgp max-med command */
+ install_element (BGP_NODE, &bgp_maxmed_admin_cmd);
+ install_element (BGP_NODE, &no_bgp_maxmed_admin_cmd);
+ install_element (BGP_NODE, &bgp_maxmed_admin_medv_cmd);
+ install_element (BGP_NODE, &no_bgp_maxmed_admin_medv_cmd);
+ install_element (BGP_NODE, &bgp_maxmed_onstartup_cmd);
+ install_element (BGP_NODE, &no_bgp_maxmed_onstartup_cmd);
+ install_element (BGP_NODE, &no_bgp_maxmed_onstartup_period_cmd);
+ install_element (BGP_NODE, &bgp_maxmed_onstartup_medv_cmd);
+ install_element (BGP_NODE, &no_bgp_maxmed_onstartup_period_medv_cmd);
+
/* bgp update-delay command */
install_element (BGP_NODE, &bgp_update_delay_cmd);
install_element (BGP_NODE, &no_bgp_update_delay_cmd);