<tag><label id="l3vpn-rd">rd <m/rd/</tag>
A shorthand for the option <cf/route distinguisher/.
- <tag><label id="l3vpn-import-target">import target <m/ec/|<m/ec-set/</tag>
+ <tag><label id="l3vpn-import-target">import target <m/ec/|<m/ec-set/|none|all</tag>
Route target extended communities specifying which routes should be
imported. Either one community or a set. A route is imported if there is
non-empty intersection between extended communities of the route and the
import target of the L3VPN protocol. Mandatory.
- <tag><label id="l3vpn-export-target">export target <m/ec/|<m/ec-set/</tag>
+ <tag><label id="l3vpn-export-target">export target <m/ec/|<m/ec-set/|none</tag>
Route target extended communities that are attached to the route in the
export direction. Either one community or a set. Other route target
extended communities are removed. Mandatory.
- <tag><label id="l3vpn-route-target">route target <m/ec/|<m/ec-set/</tag>
+ <tag><label id="l3vpn-route-target">route target <m/ec/|<m/ec-set/|none</tag>
A shorthand for both <cf/import target/ and <cf/export target/.
</descrip>
l3vpn_proto_start: proto_start L3VPN
{
this_proto = proto_config_new(&proto_l3vpn, $1);
+
+ L3VPN_CFG->import_target = RT_UNDEF;
+ L3VPN_CFG->export_target = RT_UNDEF;
};
| mpls_channel
| RD VPN_RD { L3VPN_CFG->rd = $2; }
| ROUTE DISTINGUISHER VPN_RD { L3VPN_CFG->rd = $3; }
+ | IMPORT TARGET ALL { L3VPN_CFG->import_target = RT_ALL; }
| IMPORT TARGET l3vpn_targets { L3VPN_CFG->import_target = $3; }
| EXPORT TARGET l3vpn_targets { L3VPN_CFG->export_target = $3; }
| ROUTE TARGET l3vpn_targets { L3VPN_CFG->import_target = L3VPN_CFG->export_target = $3; }
l3vpn_targets:
ec_item { f_tree_only_rt($1); $$ = $1; }
| '[' ec_items ']' { f_tree_only_rt($2); $$ = build_tree($2); }
+ | '[' ']' { $$ = RT_NONE; }
+ | NONE { $$ = RT_NONE; }
;
* - check for simple nodes in export route
* - replace pair of channels with shared channel for one address family
* - improve route comparisons in VRFs
- * - optional import/export target all
* - optional support for route origins
* - optional automatic assignment of RDs
* - MPLS-in-IP encapsulation
return 1;
}
+const struct f_tree l3vpn_rt_all = {
+ .from = { .type = T_EC, .val.ec = 0 },
+ .to = { .type = T_EC, .val.ec = ~0 },
+};
+
static int
l3vpn_import_targets(struct l3vpn_proto *p, const struct adata *list)
{
+ if (p->import_target == RT_ALL)
+ return 1;
+
+ if (p->import_target == RT_NONE)
+ return 0;
+
return (p->import_target_one) ?
ec_set_contains(list, p->import_target->from.val.ec) :
eclist_match_set(list, p->import_target);
l3vpn_prepare_import_targets(struct l3vpn_proto *p)
{
const struct f_tree *t = p->import_target;
- p->import_target_one = !t->left && !t->right && (t->from.val.ec == t->to.val.ec);
+ p->import_target_one = t && !t->left && !t->right && (t->from.val.ec == t->to.val.ec);
}
static void
if (rd_zero(cf->rd))
cf_error("Route distinguisher not specified");
- if (!cf->import_target && !cf->export_target)
+ if ((cf->import_target == RT_UNDEF) && (cf->export_target == RT_UNDEF))
cf_error("Route target not specified");
- if (!cf->import_target)
+ if (cf->import_target == RT_UNDEF)
cf_error("Import target not specified");
- if (!cf->export_target)
+ if (cf->export_target == RT_UNDEF)
cf_error("Export target not specified");
}
#ifndef _BIRD_L3VPN_H_
#define _BIRD_L3VPN_H_
+extern const struct f_tree l3vpn_rt_all;
+
+#define RT_ALL (&l3vpn_rt_all)
+#define RT_NONE ((struct f_tree *) NULL)
+#define RT_UNDEF ((struct f_tree *) 1)
+
struct l3vpn_config {
struct proto_config c;
vpn_rd rd;
- struct f_tree *import_target;
- struct f_tree *export_target;
+ const struct f_tree *import_target;
+ const struct f_tree *export_target;
};
struct l3vpn_proto {
struct channel *vpn6_channel;
vpn_rd rd;
- struct f_tree *import_target;
- struct f_tree *export_target;
+ const struct f_tree *import_target;
+ const struct f_tree *export_target;
u32 *export_target_data;
uint export_target_length;
uint import_target_one;