else if (aggregate->egp_origin_count > 0)
origin = BGP_ORIGIN_EGP;
+ if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
+ origin = aggregate->origin;
+
if (aggregate->as_set) {
if (aggregate->aspath)
/* Retrieve aggregate route's as-path.
else if (aggregate->egp_origin_count > 0)
origin = BGP_ORIGIN_EGP;
+ if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
+ origin = aggregate->origin;
+
if (aggregate->as_set) {
/* Compute aggregate route's as-path.
*/
else if (aggregate->egp_origin_count > 0)
origin = BGP_ORIGIN_EGP;
+ if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
+ origin = aggregate->origin;
+
if (aggregate->as_set) {
/* Retrieve aggregate route's as-path.
*/
#define AGGREGATE_AS_SET 1
#define AGGREGATE_AS_UNSET 0
+static const char *bgp_origin2str(uint8_t origin)
+{
+ switch (origin) {
+ case BGP_ORIGIN_IGP:
+ return "igp";
+ case BGP_ORIGIN_EGP:
+ return "egp";
+ case BGP_ORIGIN_INCOMPLETE:
+ return "incomplete";
+ }
+ return "n/a";
+}
+
static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
afi_t afi, safi_t safi)
{
}
static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
- safi_t safi, const char *rmap, uint8_t summary_only,
- uint8_t as_set)
+ safi_t safi, const char *rmap,
+ uint8_t summary_only, uint8_t as_set,
+ uint8_t origin)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
aggregate->as_set = as_set_new;
aggregate->safi = safi;
+ /* Override ORIGIN attribute if defined.
+ * E.g.: Cisco and Juniper set ORIGIN for aggregated address
+ * to IGP which is not what rfc4271 says.
+ * This enables the same behavior, optionally.
+ */
+ aggregate->origin = origin;
if (rmap) {
XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
DEFUN (aggregate_address,
aggregate_address_cmd,
- "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
+ "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Generate AS set path information\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n"
"Apply route map to aggregate network\n"
- "Name of route map\n")
+ "Name of route map\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n")
{
int idx = 0;
argv_find(argv, argc, "A.B.C.D/M", &idx);
char *prefix = argv[idx]->arg;
char *rmap = NULL;
+ uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
: AGGREGATE_AS_UNSET;
idx = 0;
if (idx)
rmap = argv[idx]->arg;
- return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
- rmap, summary_only, as_set);
+ idx = 0;
+ if (argv_find(argv, argc, "origin", &idx)) {
+ if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
+ origin = BGP_ORIGIN_IGP;
+ if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
+ origin = BGP_ORIGIN_EGP;
+ if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
+ origin = BGP_ORIGIN_INCOMPLETE;
+ }
+
+ return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty), rmap,
+ summary_only, as_set, origin);
}
DEFUN (aggregate_address_mask,
aggregate_address_mask_cmd,
- "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
+ "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
"Configure BGP aggregate entries\n"
"Aggregate address\n"
"Aggregate mask\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n"
"Apply route map to aggregate network\n"
- "Name of route map\n")
+ "Name of route map\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n")
{
int idx = 0;
argv_find(argv, argc, "A.B.C.D", &idx);
char *mask = argv[idx + 1]->arg;
bool rmap_found;
char *rmap = NULL;
+ uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
: AGGREGATE_AS_UNSET;
idx = 0;
return CMD_WARNING_CONFIG_FAILED;
}
+ idx = 0;
+ if (argv_find(argv, argc, "origin", &idx)) {
+ if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
+ origin = BGP_ORIGIN_IGP;
+ if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
+ origin = BGP_ORIGIN_EGP;
+ if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
+ origin = BGP_ORIGIN_INCOMPLETE;
+ }
+
return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
- rmap, summary_only, as_set);
+ rmap, summary_only, as_set, origin);
}
DEFUN (no_aggregate_address,
no_aggregate_address_cmd,
- "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
+ "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n"
"Apply route map to aggregate network\n"
- "Name of route map\n")
+ "Name of route map\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n")
{
int idx = 0;
argv_find(argv, argc, "A.B.C.D/M", &idx);
DEFUN (no_aggregate_address_mask,
no_aggregate_address_mask_cmd,
- "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
+ "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate address\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n"
"Apply route map to aggregate network\n"
- "Name of route map\n")
+ "Name of route map\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n")
{
int idx = 0;
argv_find(argv, argc, "A.B.C.D", &idx);
DEFUN (ipv6_aggregate_address,
ipv6_aggregate_address_cmd,
- "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
+ "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Generate AS set path information\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n"
"Apply route map to aggregate network\n"
- "Name of route map\n")
+ "Name of route map\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n")
{
int idx = 0;
argv_find(argv, argc, "X:X::X:X/M", &idx);
char *prefix = argv[idx]->arg;
char *rmap = NULL;
bool rmap_found;
+ uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
: AGGREGATE_AS_UNSET;
if (rmap_found)
rmap = argv[idx]->arg;
+ idx = 0;
+ if (argv_find(argv, argc, "origin", &idx)) {
+ if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
+ origin = BGP_ORIGIN_IGP;
+ if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
+ origin = BGP_ORIGIN_EGP;
+ if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
+ origin = BGP_ORIGIN_INCOMPLETE;
+ }
+
return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
- sum_only, as_set);
+ sum_only, as_set, origin);
}
DEFUN (no_ipv6_aggregate_address,
no_ipv6_aggregate_address_cmd,
- "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
+ "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n"
"Apply route map to aggregate network\n"
- "Name of route map\n")
+ "Name of route map\n"
+ "BGP origin code\n"
+ "Remote EGP\n"
+ "Local IGP\n"
+ "Unknown heritage\n")
{
int idx = 0;
argv_find(argv, argc, "X:X::X:X/M", &idx);
if (bgp_aggregate->rmap.name)
vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
+ if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
+ vty_out(vty, " origin %s",
+ bgp_origin2str(bgp_aggregate->origin));
+
vty_out(vty, "\n");
}
}