/* $XORP: xorp/etc/templates/bgp.tp,v 1.99 2008/08/06 08:23:24 abittau Exp $ */

protocols {
    bgp {
	targetname: txt = "bgp";
	bgp-id: ipv4;
	local-as: txt;
	enable-4byte-as-numbers: bool = false;
	internal-distance: u32;
	external-distance: u32;

	route-reflector {
	    cluster-id: ipv4;
	    disable: bool = false;
	}

	confederation {
	    identifier: u32;
	    disable: bool = false;
	}

	damping {
	    half-life: u32 = 15;
	    max-suppress: u32 = 60;
	    reuse: u32 = 750;
	    suppress: u32 = 3000;
	    disable: bool = false;
	}

	peer @: txt {
	    peer-port: u32 = 179;
	    local-port: u32 = 179;
	    local-ip: txt;
	    local-dev: txt = "";
	    as: txt;
	    next-hop: ipv4;
	    next-hop6: ipv6;
	    holdtime: u32 = 90;
	    delay-open-time: u32 = 0;
	    client: bool = false;
	    confederation-member: bool = false;
	    prefix-limit {
		maximum: u32 = 250000;
		disable: bool = false;
	    }

	    disable: bool = false;
	    enabled: bool;			/* %deprecated */

	    ipv4-unicast: bool = true;
	    ipv4-multicast: bool = false;
	    ipv6-unicast: bool = false;
	    ipv6-multicast: bool = false;

/*	    md5-password: txt = "";*/

	    import: txt = "";
	    export: txt = "";
	}

/*
	network4 @: ipv4net {
	    next-hop:ipv4;
	    unicast:bool = true;
	    multicast:bool = false;
	}

	network6 @: ipv6net {
	    next-hop:ipv6;
	    unicast:bool = true;
	    multicast:bool = false;
	}
*/

	traceoptions {
	    flag {
		verbose {
		    disable:		toggle = false;
		}
		all {
		    disable:		toggle = false;
		}
		message-in {
		    disable:		toggle = false;
		}
		message-out {
		    disable:		toggle = false;
		}
		state-change {
		    disable:		toggle = false;
		}
		policy-configuration {
		    disable:		toggle = false;
		}
	    }
	}

	import: txt = "";
	export: txt = "";
    }
}

policy {
    policy-statement @: txt {
	term @: txt {
	    from {
		as-path:		txt;
		as-path-list:		txt;
		community:		txt;
		community-list:		txt;
		neighbor:		ipv4range;
		origin:			u32;
		med:			u32range;
		localpref:		u32range;
	    }
	    to {
		as-path:		txt;
		as-path-list:		txt;
		community:		txt;
		neighbor:		ipv4range;
		origin:			u32;
		med:			u32range;
		localpref:		u32range;
		was-aggregated:		bool;
	    }
	    then {
		as-path-prepend:	u32;
		as-path-expand:		u32;
		community:		txt;
		community-add:		txt;
		community-del:		txt;
		origin:			u32;
		med:			u32;
		med-remove:		bool;
		localpref:		u32;
		aggregate-prefix-len:	u32;
		aggregate-brief-mode:	bool;
	    }
	}
    }

    community-list @: txt {
	elements: txt;
    }

    as-path-list @: txt {
	elements: txt;
    }
}

protocols {
    bgp {
	%modinfo: provides bgp;
	%modinfo: depends rib;
	%modinfo: depends policy;
	%modinfo: path "xorp_bgp";
	%modinfo: default_targetname "bgp";
	%modinfo: status_method xrl "$(bgp.targetname)/common/0.1/get_status->status:u32&reason:txt";
	%modinfo: shutdown_method xrl "$(bgp.targetname)/common/0.1/shutdown";

	%mandatory: $(@.bgp-id);
	%mandatory: $(@.local-as);
	%mandatory: $(@.targetname);

	targetname {
	    %user-hidden: "XRL target name";
	    %help: short "XRL target name";
	    %set:;
	}

	internal-distance {
            %help:      short "Administrative Distance for IBGP";
            %allow-range: $(@) "0" "255" %help: "Administrative Distance for IBGP";
            %set:       xrl "rib/rib/0.1/set_protocol_admin_distance?protocol:txt=ibgp&ipv4:bool=true&ipv6:bool=false&unicast:bool=true&multicast:bool=false&admin_distance:u32=$(@)";
        }

	external-distance {
            %help:      short "Administrative Distance for EBGP";
            %allow-range: $(@) "0" "255" %help: "Administrative Distance for EBGP";
            %set:       xrl "rib/rib/0.1/set_protocol_admin_distance?protocol:txt=ebgp&ipv4:bool=true&ipv6:bool=false&unicast:bool=true&multicast:bool=false&admin_distance:u32=$(@)";
        }

    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=network4&type:txt=ipv4net&access:txt=r&id:u32=10";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=network6&type:txt=ipv6net&access:txt=r&id:u32=12";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=nexthop4&type:txt=ipv4nexthop&access:txt=rw&id:u32=11";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=nexthop6&type:txt=ipv6nexthop&access:txt=rw&id:u32=13";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=aspath&type:txt=aspath&access:txt=rw&id:u32=14";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=community&type:txt=set_com32&access:txt=rw&id:u32=18";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=neighbor&type:txt=ipv4&access:txt=r&id:u32=16";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=origin&type:txt=u32&access:txt=rw&id:u32=15";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=med&type:txt=u32&access:txt=rw&id:u32=19";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=med_remove&type:txt=bool&access:txt=rw&id:u32=20";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=localpref&type:txt=u32&access:txt=rw&id:u32=17";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=aggregate_prefix_len&type:txt=u32&access:txt=w&id:u32=21";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=aggregate_brief_mode&type:txt=bool&access:txt=w&id:u32=22";
    %create: xrl "$(policy.targetname)/policy/0.1/add_varmap?protocol:txt=bgp&variable:txt=was_aggregated&type:txt=bool&access:txt=r&id:u32=23";

	bgp-id {
	    %set: xrl "$(bgp.targetname)/bgp/0.3/set_bgp_id?id:ipv4=$(@)";
	    %get: xrl "$(bgp.targetname)/bgp/0.3/get_bgp_id->id:ipv4";
	}

	local-as {
	    /* we'd like to specify this as an int, but 4 byte AS
               numbers are specified as <int>.<int> so this has to be text */
	    /* %allow-range: $(@) "1" "65535" ; */
            %help: short "Local AS number: <int> or <int>.<int>";
	    %set: xrl "$(bgp.targetname)/bgp/0.3/set_local_as?as:txt=$(@)";
	    %get: xrl "$(bgp.targetname)/bgp/0.3/get_local_as->as:txt";
	}
	
	enable-4byte-as-numbers {
            %help: short "Enable extended AS numbers";
            %set: xrl "$(bgp.targetname)/bgp/0.3/set_4byte_as_support?enable:bool=$(@)";
	}

	route-reflector {
	    %mandatory: $(@.cluster-id);

	    %create: xrl "$(bgp.targetname)/bgp/0.3/set_cluster_id?cluster_id:ipv4=$(@.cluster-id)&disable:bool=$(@.disable)";
	    %activate: xrl "$(bgp.targetname)/bgp/0.3/set_cluster_id?cluster_id:ipv4=$(@.cluster-id)&disable:bool=$(@.disable)";
	    %delete: xrl "$(bgp.targetname)/bgp/0.3/set_cluster_id?cluster_id:ipv4=$(@.cluster-id)&disable:bool=`~$(@.disable.DEFAULT)`";

	    cluster-id {
		%set:;
	    }

	    disable {
		%set:;
	    }
	}

	confederation {
	    %mandatory: $(@.identifier);

	    %create: xrl "$(bgp.targetname)/bgp/0.3/set_confederation_identifier?as:txt=$(@.identifier)&disable:bool=$(@.disable)";
	    %activate: xrl "$(bgp.targetname)/bgp/0.3/set_confederation_identifier?as:txt=$(@.identifier)&disable:bool=$(@.disable)";
	    %delete: xrl "$(bgp.targetname)/bgp/0.3/set_confederation_identifier?as:txt=$(@.identifier)&disable:bool=`~$(@.disable.DEFAULT)`";

	    identifier {
		%set:;
	    }

	    disable {
		%set:;
	    }
	}

	damping {

	    %create: xrl "$(bgp.targetname)/bgp/0.3/set_damping?half_life:u32=$(@.half-life)&max_suppress:u32=$(@.max-suppress)&reuse:u32=$(@.reuse)&suppress:u32=$(@.suppress)&disable:bool=$(@.disable)";
	    %activate: xrl "$(bgp.targetname)/bgp/0.3/set_damping?half_life:u32=$(@.half-life)&max_suppress:u32=$(@.max-suppress)&reuse:u32=$(@.reuse)&suppress:u32=$(@.suppress)&disable:bool=$(@.disable)";
	    %delete: xrl "$(bgp.targetname)/bgp/0.3/set_damping?half_life:u32=$(@.half-life)&max_suppress:u32=$(@.max-suppress)&reuse:u32=$(@.reuse)&suppress:u32=$(@.suppress)&disable:bool=`~$(@.disable.DEFAULT)`";

	    half-life {
		%set:;
	    }

	    max-suppress {
		%set:;
	    }

	    reuse {
		%set:;
	    }

	    suppress {
		%set:;
	    }
	}

	peer @ {
	    %mandatory: $(@.as);
	    %mandatory: $(@.next-hop);
	    %mandatory: $(@.local-port);
	    %mandatory: $(@.peer-port);
	    %mandatory: $(@.local-ip);

	    %create: xrl "$(bgp.targetname)/bgp/0.3/add_peer?local_dev:txt=$(@.local-dev)&local_ip:txt=$(@.local-ip)&local_port:u32=$(@.local-port)&peer_ip:txt=$(@)&peer_port:u32=$(@.peer-port)&as:txt=$(@.as)&next_hop:ipv4=$(@.next-hop)&holdtime:u32=$(@.holdtime)";
	    %delete: xrl "$(bgp.targetname)/bgp/0.3/delete_peer?local_ip:txt=$(@.local-ip)&local_port:u32=$(@.local-port)&peer_ip:txt=$(@)&peer_port:u32=$(@.peer-port)";
	    %activate: xrl "$(bgp.targetname)/bgp/0.3/activate?local_ip:txt=$(@.local-ip)&local_port:u32=$(@.local-port)&peer_ip:txt=$(@)&peer_port:u32=$(@.peer-port)";
/*
	    peer-port {
		%set: xrl "$(bgp.targetname)/bgp/0.3/change_peer_port?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&new_peer_port:u32=$(@)";
	    }
*/
/*
	    local-port {
		%set: xrl "$(bgp.targetname)/bgp/0.3/change_local_port?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&new_local_port:u32=$(@)";
	    }
*/

	    local-dev {
                %set: xrl "$(bgp.targetname)/bgp/0.3/change_local_ip?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&new_local_ip:txt=$(peer.@.local-ip)&new_local_dev:txt=$(@)";
	    }


	    local-ip {
		%set: xrl "$(bgp.targetname)/bgp/0.3/change_local_ip?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&new_local_ip:txt=$(@)&new_local_dev:txt=$(peer.@.local-dev)";
	    }

/*
	    md5-password {
		%set:;
	    }
*/

	    as {
		/*%allow-range: $(@) "1" "65535" %help: "The peer AS number";*/
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_peer_as?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&peer_as:txt=$(@)";
	    }

	    holdtime {
		%allow-range: $(@) "0" "0" %help: "Disable holdtime";
		%allow-range: $(@) "3" "65535" %help: "Time to wait for peer";
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_holdtime?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&holdtime:u32=$(@)";
	    }

	    delay-open-time {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_delay_open_time?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&delay_open_time:u32=$(@)";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_delay_open_time?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&delay_open_time:u32=$(DEFAULT)";
	    }

	    client {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_route_reflector_client?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&state:bool=$(@)";
	    }

	    confederation-member {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_confederation_member?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&state:bool=$(@)";
	    }

	    prefix-limit {
		%create: xrl "$(bgp.targetname)/bgp/0.3/set_prefix_limit?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&maximum:u32=$(@.maximum)&state:bool=`~$(@.disable)`";
		%activate: xrl "$(bgp.targetname)/bgp/0.3/set_prefix_limit?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&maximum:u32=$(@.maximum)&state:bool=`~$(@.disable)`";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_prefix_limit?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&maximum:u32=$(@.maximum)&state:bool=$(@.disable.DEFAULT)";

		maximum {
		    %set:;
		}

		disable {
		    %set:;
		}
	    }

	    next-hop {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_nexthop4?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&next_hop:ipv4=$(@)";
	    }

	    next-hop6 {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_nexthop6?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&next_hop:ipv6=$(@)";
	    }

	    disable {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_peer_state?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&toggle:bool=`~$(@)`";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_peer_state?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&toggle:bool=`~$(DEFAULT)`";
	    }

	    enabled {
		%deprecated: "Statement 'enabled: true/false' is replaced with 'disable: false/true'";
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_peer_state?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&toggle:bool=$(@)";
	    }

	    ipv4-unicast {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv4.Unicast&toggle:bool=$(@)";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv4.Unicast&toggle:bool=$(DEFAULT)";
	    }

	    ipv4-multicast {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv4.Multicast&toggle:bool=$(@)";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv4.Multicast&toggle:bool=$(DEFAULT)";
	    }

	    ipv6-unicast {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv6.Unicast&toggle:bool=$(@)";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv6.Unicast&toggle:bool=$(DEFAULT)";
	    }

	    ipv6-multicast {
		%set: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv6.Multicast&toggle:bool=$(@)";
		%delete: xrl "$(bgp.targetname)/bgp/0.3/set_parameter?local_ip:txt=$(peer.@.local-ip)&local_port:u32=$(peer.@.local-port)&peer_ip:txt=$(peer.@)&peer_port:u32=$(peer.@.peer-port)&parameter:txt=MultiProtocol.IPv6.Multicast&toggle:bool=$(DEFAULT)";
	    }

	    import {
	        %help: short "Import policy";
	        %delete: xrl "$(policy.targetname)/policy/0.1/import?protocol:txt=$(bgp.targetname)&policies:txt=&modifier:txt=neighbor == $(peer.@);";
	        %set: xrl "$(policy.targetname)/policy/0.1/import?protocol:txt=$(bgp.targetname)&policies:txt=$(@)&modifier:txt=neighbor == $(peer.@);";
	    }

	    export {
	        %help: short "Export policy";
	        %delete: xrl "$(policy.targetname)/policy/0.1/export?protocol:txt=$(bgp.targetname)&policies:txt=&modifier:txt=neighbor == $(peer.@);";
	        %set: xrl "$(policy.targetname)/policy/0.1/export?protocol:txt=$(bgp.targetname)&policies:txt=$(@)&modifier:txt=neighbor == $(peer.@);";
	    }
	} /* peer */

/*
	network4 @: ipv4net {
	    %mandatory: $(@.next-hop);

	    %activate: xrl "$(bgp.targetname)/bgp/0.3/originate_route4?nlri:ipv4net=$(@)&next_hop:ipv4=$(@.next-hop)&unicast:bool=$(@.unicast)&multicast:bool=$(@.multicast)";
	    %delete: xrl "$(bgp.targetname)/bgp/0.3/withdraw_route4?nlri:ipv4net=$(@)&unicast:bool=$(@.unicast)&multicast:bool=$(@.multicast)";

	    next-hop {
		%set:;
	    }

	    unicast {
		%set:;
	    }

	    multicast {
		%set:;
	    }
	}

	network6 @: ipv6net {
	    %mandatory: $(@.next-hop);

	    %activate: xrl "$(bgp.targetname)/bgp/0.3/originate_route6?nlri:ipv6net=$(@)&next_hop:ipv6=$(@.next-hop)&unicast:bool=$(@.unicast)&multicast:bool=$(@.multicast)";
	    %delete: xrl "$(bgp.targetname)/bgp/0.3/withdraw_route6?nlri:ipv6net=$(@)&unicast:bool=$(@.unicast)&multicast:bool=$(@.multicast)";

	    next-hop {
		%set:;
	    }

	    unicast {
		%set:;
	    }

	    multicast {
		%set:;
	    }
	}
*/

	traceoptions {
	    flag {
		/* Deliberately not included in all */
		verbose {
		    disable {
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=xlog_verbose&enable:bool=`~$(@)`";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=xlog_verbose&enable:bool=$(DEFAULT)";
		    }
		}

		all {
		    disable {
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_in&enable:bool=`~$(@)`";
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_out&enable:bool=`~$(@)`";
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_state_change&enable:bool=`~$(@)`";
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_policy_configure&enable:bool=`~$(@)`";

			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_in&enable:bool=$(DEFAULT)";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_out&enable:bool=$(DEFAULT)";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_state_change&enable:bool=$(DEFAULT)";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_policy_configure&enable:bool=$(DEFAULT)";
		    }
		}

		message-in {
		    disable {
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_in&enable:bool=`~$(@)`";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_in&enable:bool=$(DEFAULT)";
		    }
		}

		message-out {
		    disable {
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_out&enable:bool=`~$(@)`";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_message_out&enable:bool=$(DEFAULT)";
		    }
		}

		state-change {
		    disable {
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_state_change&enable:bool=`~$(@)`";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_state_change&enable:bool=$(DEFAULT)";
		    }
		}

		policy-configuration {
		    disable {
			%set: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_policy_configure&enable:bool=`~$(@)`";
			%delete: xrl "$(bgp.targetname)/bgp/0.3/trace?tvar:txt=trace_policy_configure&enable:bool=$(DEFAULT)";
		    }
		}
	    }
	}

	import {
	    %help: short "Import policy";
	    %delete: xrl "$(policy.targetname)/policy/0.1/import?protocol:txt=$(bgp.targetname)&policies:txt=&modifier:txt=";
	    %create:;
	    %set: xrl "$(policy.targetname)/policy/0.1/import?protocol:txt=$(bgp.targetname)&policies:txt=$(@)&modifier:txt=";
	}
	export {
	    %help: short "Export policy";
	    %delete: xrl "$(policy.targetname)/policy/0.1/export?protocol:txt=$(bgp.targetname)&policies:txt=&modifier:txt=";
	    %create:;
	    %set: xrl "$(policy.targetname)/policy/0.1/export?protocol:txt=$(bgp.targetname)&policies:txt=$(@)&modifier:txt=";
	}
	%activate: xrl "$(policy.targetname)/policy/0.1/import?protocol:txt=$(bgp.targetname)&policies:txt=$(@.import)&modifier:txt=";
	%activate: xrl "$(policy.targetname)/policy/0.1/export?protocol:txt=$(bgp.targetname)&policies:txt=$(@.export)&modifier:txt=";
    }
}

protocols {
    bgp {
	%help: short "Configure BGP inter-domain routing";

	targetname {
	}

	bgp-id {
	    %help: short "Set the BGP identifier (must be an IPv4 address)";
	}

	local-as {
	    %help: short "Set the Autonomous System (AS) number for this domain";
	}

	route-reflector {
	    %help: short "Make this router a route reflector";

	    cluster-id {
		%help: short "CLUSTER_ID for this route reflector";
	    }

	    disable {
		%help: short "disable this router reflector";
	    }
	}

	confederation {
	    %help: short "Make this router part of a confederation";

	    identifier {
		%help: short "AS number used to non confederation peers";
	    }

	    disable {
		%help: short "disable confederations";
	    }
	}

	damping {
	    %help: short "Route Flap Damping";

	    half-life {
		%help: short "Decay half-life in minutes";
	    }

	    max-suppress {
		%help: short "Maximum hold-down time in minutes";
	    }

	    reuse {
		%help: short "Reuse threshold";
	    }

	    suppress {
		%help: short "Cutoff (suppression) threshold";
	    }

	    disable {
		%help: short "disable damping";
	    }
	}

	peer @ {
	    %help: short "Configure a peering session with another router.";

	    peer-port {
		%help: short "Set the TCP port used by on the remote router.";
	    }

	    local-port {
		%help: short "Set the TCP port used by BGP on this router.";
	    }

	    local-ip {
		%help: short "Set the IP address on this router to use for this peering.";
	    }

	    as {
		%help: short "Set the AS number of this peer.";
	    }

	    holdtime {
		%help: short "Set the length of time before idle timeout.";
	    }

	    delay-open-time {
		%help: short "Set the delay open time.";
	    }

	    client {
		%help: short
			"Set to true if the peer is a route reflector client.";
	    }

	    confederation-member {
		%help: short
			"Set to true if the peer is a confederation member";
	    }

	    prefix-limit {
		%help: short "Threshold for the number of prefixes that can be accepted.";

		maximum {
		    %help: short "Number of prefixes to accept before tearing down session";
		}

		disable {
		    %help: short "Disable the prefix-limit";
		}
	    }

	    next-hop {
		%help: short "IPv4 next-hop";
	    }

	    next-hop6 {
		%help: short "IPv6 next-hop";
	    }

	    disable {
		%help: short "Disable this peering.";
	    }

	    enabled {
		%help: short "Enable this peering.";
	    }

	    client {
		%help: short "Treat peer as a route reflector client.";
	    }

/*
	    md5-password {
		%help: short "Enable and set the password for TCP-MD5 authentication with this peer.";
	    }
*/

	    set-parameter {
	    }

	    ipv4-unicast {
		%help: short "IPv4 Unicast";
	    }

	    ipv4-multicast {
		%help: short "IPv4 Multicast";
	    }

	    ipv6-unicast {
		%help: short "IPv6 Unicast";
	    }

	    ipv6-multicast {
		%help: short "IPv6 Multicast";
	    }
	}

	traceoptions {
	    %help:	short "Configure the tracing options";
	    flag {
		%help:	short "Configure the tracing operation to perform";

		verbose {
		    %help:	short	"Configure verbose traces";
		    disable {
			%help:	short	"Disable verbose traces";
		    }
		}

		all {
		    %help:	short	"Configure all tracing operations";
		    disable {
			%help:	short	"Disable all tracing operations";
		    }
		}

		message-in {
		    %help:	short	"Configure receive message tracing";
		    disable {
			%help:	short	"Disable receive message tracing";
		    }
		}

		message-out {
		    %help:	short	"Configure send message tracing";
		    disable {
			%help:	short	"Disable send message tracing";
		    }
		}

		state-change {
		    %help:	short	"Configure FSM state change tracing";
		    disable {
			%help:	short	"Disable FSM state change tracing";
		    }
		}

		policy-configuration {
		    %help:	short	"Configure policy configuration tracing";
		    disable {
			%help:	short	"Disable policy configuration tracing";
		    }
		}
	    }
	}
    }
}

policy {
    policy-statement @: txt {
	term @: txt {

	    from {
		as-path {
		    %help: short "BGP AS path";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=aspath REGEX '$(@)';";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		as-path-list {
		    %help: short "Named set of BGP AS paths";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=aspath REGEX SET $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		community {
		    %help: short "BGP community";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=community $(<>) (ctr 'set_com32' '$(@)');";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		community-list {
		    %help: short "Named set of BGP communities";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=community ne_int SET $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		neighbor {
		    %help: short "Neighbor router";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=neighbor $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		origin {
		    %help: short "BGP origin attribute";
		    %allow-range: $(@) "0" "2" %help: "Origin attribute: 0 for IGP, 1 for EGP, 2 for incomplete";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=origin $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		med {
		    %help: short "BGP MED attribute";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=med $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
		localpref {
		    %help: short "Local preference associated with a route";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=localpref $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=0&order:txt=$(#)&statement:txt=";
		}
	    } /* from */

	    to {
		as-path {
		    %help: short "BGP AS path";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=aspath REGEX '$(@)';";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		as-path-list {
		    %help: short "Named set of BGP AS paths";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=aspath REGEX SET $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		community {
		    %help: short "BGP community";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=community ne_int (ctr 'set_com32' '$(@)');";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		neighbor {
		    %help: short "Neighbor router";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=neighbor $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		origin {
		    %help: short "BGP origin attribute";
		    %allow-range: $(@) "0" "2" %help: "Origin attribute: 0 for IGP, 1 for EGP, 2 for incomplete";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=origin $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		med {
		    %help: short "BGP MED attribute";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=med $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		localpref {
		    %help: short "Local preference associated with a route";
		    %allow-operator: ":" "==" "!=" "<" ">" "<=" ">=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=localpref $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
		was-aggregated {
		    %help: short "True if this route contributed to origination of an aggregate";
		    %allow-operator: ":" "==" "!=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=was_aggregated $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=1&order:txt=$(#)&statement:txt=";
		}
	    } /* to */

	    then {
		as-path-prepend {
		    %help: short "Prepend AS numbers to an AS path";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=aspath = $(@) + aspath;";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		as-path-expand {
		    %help: short "Prepend AS numbers prior to adding local-as";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=aspath = $(@) * aspath;";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		community {
		    %help: short "Set the BGP communities in the route";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=community $(<>) (ctr 'set_com32' '$(@)');";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		community-add {
		    %help: short "Add BGP communities to the route";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=community = community + (ctr 'set_com32' '$(@)');";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		community-del {
		    %help: short "Remove BGP communities from the route";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=community = community - (ctr 'set_com32' '$(@)');";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		origin {
		    %help: short "Set the BGP origin attribute";
		    %allow-range: $(@) "0" "2" %help: "Origin attribute: 0 for IGP, 1 for EGP, 2 for incomplete";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=origin $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		med {
		    %help: short "Set the BGP MED attribute";
		    %allow-operator: ":" "=" "sub" "add" "mul" "div" "lshift" "rshift" "bit_and" "bit_or" "bit_xor" "+=" "-=" "*=" "/=" "<<=" ">>=" "&=" "|=" "^=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=med $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		med-remove {
		    %help: short "Remove BGP MED attribute";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=med_remove $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		localpref {
		    %help: short "Set the local preference";
		    %allow-operator: ":" "=" "sub" "add" "mul" "div" "lshift" "rshift" "bit_and" "bit_or" "bit_xor" "+=" "-=" "*=" "/=" "<<=" ">>=" "&=" "|=" "^=";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=localpref $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		aggregate-prefix-len {
		    %help: short "Originate an aggregate route with this prefix length";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=aggregate_prefix_len $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
		aggregate-brief-mode {
		    %help: short "Do not generate AS_SETs for aggregate routes";
		    %set: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=aggregate_brief_mode $(<>) $(@);";
		    %delete: xrl "$(policy.targetname)/policy/0.1/update_term_block?policy:txt=$(policy-statement.@)&term:txt=$(term.@)&block:u32=2&order:txt=$(#)&statement:txt=";
		}
	    } /* then */

	} /* term */
    } /* policy statement */

    community-list @: txt {
	%help: short "Named set of BGP communities";
	%delete: xrl "$(policy.targetname)/policy/0.1/delete_set?set:txt=$(@)";
	%create: xrl "$(policy.targetname)/policy/0.1/create_set?set:txt=$(@)";

	elements {
	    %help: short "Elements in the named set of BGP communities";
	    %set: xrl "$(policy.targetname)/policy/0.1/update_set?type:txt=set_com32&set:txt=$(community-list.@)&elements:txt=$(@)";
	}
    }

    as-path-list @: txt {
	%help: short "Named set of BGP AS paths";
	%delete: xrl "$(policy.targetname)/policy/0.1/delete_set?set:txt=$(@)";
	%create: xrl "$(policy.targetname)/policy/0.1/create_set?set:txt=$(@)";

	elements {
	    %help: short "Elements in the named set of BGP AS paths";
	    %set: xrl "$(policy.targetname)/policy/0.1/update_set?type:txt=set_str&set:txt=$(as-path-list.@)&elements:txt=$(@)";
	}
    }
}
