mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 16:20:08 +00:00
Merge pull request #5183 from opensourcerouting/zebra-route-map-nb
yang/zebra: migrate route map to northbound
This commit is contained in:
commit
e0bf2057b4
@ -148,6 +148,12 @@ void route_map_instance_show(struct vty *vty, struct lyd_node *dnode,
|
||||
SKIP_RULE("ipv6 next-hop type");
|
||||
SKIP_RULE("metric");
|
||||
SKIP_RULE("tag");
|
||||
/* Zebra specific match conditions. */
|
||||
SKIP_RULE("ip address prefix-len");
|
||||
SKIP_RULE("ipv6 address prefix-len");
|
||||
SKIP_RULE("ip next-hop prefix-len");
|
||||
SKIP_RULE("source-protocol");
|
||||
SKIP_RULE("source-instance");
|
||||
|
||||
vty_out(vty, " match %s %s\n", rmr->cmd->str,
|
||||
rmr->rule_str ? rmr->rule_str : "");
|
||||
@ -158,6 +164,8 @@ void route_map_instance_show(struct vty *vty, struct lyd_node *dnode,
|
||||
/* Skip all sets implemented by northbound. */
|
||||
SKIP_RULE("metric");
|
||||
SKIP_RULE("tag");
|
||||
/* Zebra specific set actions. */
|
||||
SKIP_RULE("src");
|
||||
|
||||
vty_out(vty, " set %s %s\n", rmr->cmd->str,
|
||||
rmr->rule_str ? rmr->rule_str : "");
|
||||
@ -666,8 +674,25 @@ void route_map_condition_show(struct vty *vty, struct lyd_node *dnode,
|
||||
vty_out(vty, " match tag %s\n",
|
||||
yang_dnode_get_string(dnode, "./tag"));
|
||||
break;
|
||||
case 100:
|
||||
/* NOTHING: custom field, should be handled by daemon. */
|
||||
case 100: /* ipv4-prefix-length */
|
||||
vty_out(vty, " match ip address prefix-len %s\n",
|
||||
yang_dnode_get_string(dnode,"./frr-zebra:ipv4-prefix-length"));
|
||||
break;
|
||||
case 101: /* ipv6-prefix-length */
|
||||
vty_out(vty, " match ipv6 address prefix-len %s\n",
|
||||
yang_dnode_get_string(dnode, "./frr-zebra:ipv6-prefix-length"));
|
||||
break;
|
||||
case 102: /* ipv4-next-hop-prefix-length */
|
||||
vty_out(vty, " match ip next-hop prefix-len %s\n",
|
||||
yang_dnode_get_string(dnode, "./frr-zebra:ipv4-prefix-length"));
|
||||
break;
|
||||
case 103: /* source-protocol */
|
||||
vty_out(vty, " match source-protocol %s\n",
|
||||
yang_dnode_get_string(dnode, "./frr-zebra:source-protocol"));
|
||||
break;
|
||||
case 104: /* source-instance */
|
||||
vty_out(vty, " match source-instance %s\n",
|
||||
yang_dnode_get_string(dnode, "./frr-zebra:source-instance"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -868,8 +893,13 @@ void route_map_action_show(struct vty *vty, struct lyd_node *dnode,
|
||||
vty_out(vty, " set tag %s\n",
|
||||
yang_dnode_get_string(dnode, "./tag"));
|
||||
break;
|
||||
case 100:
|
||||
/* NOTHING: custom field, should be handled by daemon. */
|
||||
case 100: /* source */
|
||||
if (yang_dnode_exists(dnode, "./frr-zebra:source-v4"))
|
||||
vty_out(vty, " set src %s\n",
|
||||
yang_dnode_get_string(dnode, "./frr-zebra:source-v4"));
|
||||
else
|
||||
vty_out(vty, " set src %s\n",
|
||||
yang_dnode_get_string(dnode, "./frr-zebra:source-v6"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -179,17 +179,27 @@ module frr-route-map {
|
||||
description "Match a route tag";
|
||||
value 10;
|
||||
}
|
||||
|
||||
/*
|
||||
* Protocol YANG models should augment the parent node to
|
||||
* contain the routing protocol specific value. The protocol
|
||||
* must also augment `condition-value` to include its specific
|
||||
* values or expand the `when` statement on the existing cases.
|
||||
*/
|
||||
enum routing-protocol-specific {
|
||||
description "Match a routing protocol specific type";
|
||||
/* zebra specific conditions. */
|
||||
enum ipv4-prefix-length {
|
||||
description "Match IPv4 prefix length";
|
||||
value 100;
|
||||
}
|
||||
enum ipv6-prefix-length {
|
||||
description "Match IPv6 prefix length";
|
||||
value 101;
|
||||
}
|
||||
enum ipv4-next-hop-prefix-length {
|
||||
description "Match next-hop prefix length";
|
||||
value 102;
|
||||
}
|
||||
enum source-protocol {
|
||||
description "Match source protocol";
|
||||
value 103;
|
||||
}
|
||||
enum source-instance {
|
||||
description "Match source protocol instance";
|
||||
value 104;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,15 +301,9 @@ module frr-route-map {
|
||||
description "Set tag";
|
||||
value 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Protocol YANG models should augment the parent node to
|
||||
* contain the routing protocol specific value. The protocol
|
||||
* must also augment `action-value` to include its specific
|
||||
* values or expand the `when` statement on the existing cases.
|
||||
*/
|
||||
enum routing-protocol-specific {
|
||||
description "Set a routing protocol specific action";
|
||||
/* zebra specific conditions. */
|
||||
enum source {
|
||||
description "Set source address for route";
|
||||
value 100;
|
||||
}
|
||||
}
|
||||
|
@ -106,4 +106,12 @@ module frr-route-types {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef frr-route-types {
|
||||
description "Route types as enumerated in `lib/route_types.txt`";
|
||||
type union {
|
||||
type frr-route-types-v4;
|
||||
type frr-route-types-v6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ module frr-zebra {
|
||||
prefix inet;
|
||||
}
|
||||
|
||||
import frr-route-map {
|
||||
prefix frr-route-map;
|
||||
}
|
||||
|
||||
import frr-route-types {
|
||||
prefix frr-route-types;
|
||||
}
|
||||
@ -1985,4 +1989,63 @@ module frr-zebra {
|
||||
}
|
||||
|
||||
// End interface model augmentation
|
||||
|
||||
augment "/frr-route-map:lib"
|
||||
+ "/frr-route-map:route-map"
|
||||
+ "/frr-route-map:entry"
|
||||
+ "/frr-route-map:match-condition"
|
||||
+ "/frr-route-map:condition-value" {
|
||||
case ipv4-prefix-length {
|
||||
when "./condition = 'ipv4-prefix-length' or
|
||||
./condition = 'ipv4-next-hop-prefix-length'";
|
||||
leaf ipv4-prefix-length {
|
||||
type uint8 {
|
||||
range "0..32";
|
||||
}
|
||||
}
|
||||
}
|
||||
case ipv6-prefix-length {
|
||||
when "./condition = 'ipv6-prefix-length'";
|
||||
leaf ipv6-prefix-length {
|
||||
type uint8 {
|
||||
range "0..128";
|
||||
}
|
||||
}
|
||||
}
|
||||
case source-protocol {
|
||||
when "./condition = 'source-protocol'";
|
||||
leaf source-protocol {
|
||||
type frr-route-types:frr-route-types;
|
||||
}
|
||||
}
|
||||
case source-instance {
|
||||
when "./condition = 'source-instance'";
|
||||
leaf source-instance {
|
||||
type uint8 {
|
||||
range "0..255";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
augment "/frr-route-map:lib"
|
||||
+ "/frr-route-map:route-map"
|
||||
+ "/frr-route-map:entry"
|
||||
+ "/frr-route-map:set-action"
|
||||
+ "/frr-route-map:action-value" {
|
||||
case source-v4 {
|
||||
when "./action = 'source'";
|
||||
leaf source-v4 {
|
||||
description "IPv4 address";
|
||||
type inet:ipv4-address;
|
||||
}
|
||||
}
|
||||
case source-v6 {
|
||||
when "./action = 'source'";
|
||||
leaf source-v6 {
|
||||
description "IPv6 address";
|
||||
type inet:ipv6-address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,12 @@ EXTRA_DIST += yang/embedmodel.py
|
||||
|
||||
dist_yangmodels_DATA += yang/frr-filter.yang
|
||||
dist_yangmodels_DATA += yang/frr-module-translator.yang
|
||||
dist_yangmodels_DATA += yang/frr-nexthop.yang
|
||||
dist_yangmodels_DATA += yang/frr-test-module.yang
|
||||
dist_yangmodels_DATA += yang/frr-interface.yang
|
||||
dist_yangmodels_DATA += yang/frr-route-map.yang
|
||||
dist_yangmodels_DATA += yang/frr-route-types.yang
|
||||
dist_yangmodels_DATA += yang/frr-zebra.yang
|
||||
dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang
|
||||
|
||||
if BFDD
|
||||
|
@ -245,6 +245,7 @@ struct quagga_signal_t zebra_signals[] = {
|
||||
static const struct frr_yang_module_info *const zebra_yang_modules[] = {
|
||||
&frr_interface_info,
|
||||
&frr_route_map_info,
|
||||
&frr_zebra_info,
|
||||
};
|
||||
|
||||
FRR_DAEMON_INFO(
|
||||
|
@ -75,6 +75,7 @@ zebra_zebra_SOURCES = \
|
||||
zebra/zebra_mlag.c \
|
||||
zebra/zebra_mlag_vty.c \
|
||||
zebra/zebra_l2.c \
|
||||
zebra/zebra_northbound.c \
|
||||
zebra/zebra_memory.c \
|
||||
zebra/zebra_dplane.c \
|
||||
zebra/zebra_mpls.c \
|
||||
@ -191,5 +192,10 @@ zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_dt.c
|
||||
endif
|
||||
endif
|
||||
|
||||
nodist_zebra_zebra_SOURCES = \
|
||||
yang/frr-nexthop.yang.c \
|
||||
yang/frr-zebra.yang.c \
|
||||
# end
|
||||
|
||||
zebra_zebra_cumulus_mlag_la_SOURCES = zebra/zebra_mlag_private.c
|
||||
zebra_zebra_cumulus_mlag_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
|
2212
zebra/zebra_northbound.c
Normal file
2212
zebra/zebra_northbound.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,8 @@
|
||||
#include "filter.h"
|
||||
#include "plist.h"
|
||||
#include "nexthop.h"
|
||||
#include "northbound_cli.h"
|
||||
#include "route_types.h"
|
||||
#include "vrf.h"
|
||||
#include "frrstr.h"
|
||||
|
||||
@ -58,82 +60,6 @@ struct nh_rmap_obj {
|
||||
|
||||
static void zebra_route_map_set_delay_timer(uint32_t value);
|
||||
|
||||
|
||||
/* Add zebra route map rule */
|
||||
static int zebra_route_match_add(struct vty *vty, const char *command,
|
||||
const char *arg, route_map_event_t type)
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(route_map_index, index);
|
||||
enum rmap_compile_rets ret;
|
||||
int retval = CMD_SUCCESS;
|
||||
|
||||
ret = route_map_add_match(index, command, arg, type);
|
||||
switch (ret) {
|
||||
case RMAP_RULE_MISSING:
|
||||
vty_out(vty, "%% Zebra Can't find rule.\n");
|
||||
retval = CMD_WARNING_CONFIG_FAILED;
|
||||
break;
|
||||
case RMAP_COMPILE_ERROR:
|
||||
vty_out(vty, "%% Zebra Argument is malformed.\n");
|
||||
retval = CMD_WARNING_CONFIG_FAILED;
|
||||
break;
|
||||
case RMAP_COMPILE_SUCCESS:
|
||||
/*
|
||||
* Nothing to do here
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Delete zebra route map rule. */
|
||||
static int zebra_route_match_delete(struct vty *vty, const char *command,
|
||||
const char *arg, route_map_event_t type)
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(route_map_index, index);
|
||||
enum rmap_compile_rets ret;
|
||||
int retval = CMD_SUCCESS;
|
||||
char *dep_name = NULL;
|
||||
const char *tmpstr;
|
||||
char *rmap_name = NULL;
|
||||
|
||||
if (type != RMAP_EVENT_MATCH_DELETED) {
|
||||
/* ignore the mundane, the types without any dependency */
|
||||
if (arg == NULL) {
|
||||
if ((tmpstr = route_map_get_match_arg(index, command))
|
||||
!= NULL)
|
||||
dep_name =
|
||||
XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
|
||||
} else {
|
||||
dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
|
||||
}
|
||||
rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
|
||||
}
|
||||
|
||||
ret = route_map_delete_match(index, command, arg, type);
|
||||
switch (ret) {
|
||||
case RMAP_RULE_MISSING:
|
||||
vty_out(vty, "%% Zebra Can't find rule.\n");
|
||||
retval = CMD_WARNING_CONFIG_FAILED;
|
||||
break;
|
||||
case RMAP_COMPILE_ERROR:
|
||||
vty_out(vty, "%% Zebra Argument is malformed.\n");
|
||||
retval = CMD_WARNING_CONFIG_FAILED;
|
||||
break;
|
||||
case RMAP_COMPILE_SUCCESS:
|
||||
/*
|
||||
* Nothing to do here
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
|
||||
XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* 'match tag TAG'
|
||||
* Match function return 1 if match is success else return 0
|
||||
*/
|
||||
@ -425,246 +351,227 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (match_ip_address_prefix_len,
|
||||
match_ip_address_prefix_len_cmd,
|
||||
"match ip address prefix-len (0-32)",
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefix length of ip address\n"
|
||||
"Match prefix length of ip address\n"
|
||||
"Prefix length\n")
|
||||
DEFPY(
|
||||
match_ip_address_prefix_len, match_ip_address_prefix_len_cmd,
|
||||
"match ip address prefix-len (0-32)$length",
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefix length of IP address\n"
|
||||
"Match prefix length of IP address\n"
|
||||
"Prefix length\n")
|
||||
{
|
||||
return zebra_route_match_add(vty, "ip address prefix-len", argv[4]->arg,
|
||||
RMAP_EVENT_MATCH_ADDED);
|
||||
const char *xpath = "./match-condition[condition='ipv4-prefix-length']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:ipv4-prefix-length", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_match_ip_address_prefix_len,
|
||||
no_match_ip_address_prefix_len_cmd,
|
||||
"no match ip address prefix-len [(0-32)]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefix length of ip address\n"
|
||||
"Match prefix length of ip address\n"
|
||||
"Prefix length\n")
|
||||
DEFPY(
|
||||
no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd,
|
||||
"no match ip address prefix-len [(0-32)]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefix length of IP address\n"
|
||||
"Match prefix length of IP address\n"
|
||||
"Prefix length\n")
|
||||
{
|
||||
char *plen = (argc == 6) ? argv[5]->arg : NULL;
|
||||
return zebra_route_match_delete(vty, "ip address prefix-len", plen,
|
||||
RMAP_EVENT_MATCH_DELETED);
|
||||
const char *xpath = "./match-condition[condition='ipv4-prefix-length']";
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (match_ipv6_address_prefix_len,
|
||||
match_ipv6_address_prefix_len_cmd,
|
||||
"match ipv6 address prefix-len (0-128)",
|
||||
MATCH_STR
|
||||
IPV6_STR
|
||||
"Match prefix length of ipv6 address\n"
|
||||
"Match prefix length of ipv6 address\n"
|
||||
"Prefix length\n")
|
||||
DEFPY(
|
||||
match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd,
|
||||
"match ipv6 address prefix-len (0-128)$length",
|
||||
MATCH_STR
|
||||
IPV6_STR
|
||||
"Match prefix length of IPv6 address\n"
|
||||
"Match prefix length of IPv6 address\n"
|
||||
"Prefix length\n")
|
||||
{
|
||||
return zebra_route_match_add(vty, "ipv6 address prefix-len",
|
||||
argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
|
||||
const char *xpath = "./match-condition[condition='ipv6-prefix-length']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:ipv6-prefix-length", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_match_ipv6_address_prefix_len,
|
||||
no_match_ipv6_address_prefix_len_cmd,
|
||||
"no match ipv6 address prefix-len [(0-128)]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
IPV6_STR
|
||||
"Match prefix length of ip address\n"
|
||||
"Match prefix length of ip address\n"
|
||||
"Prefix length\n")
|
||||
DEFPY(
|
||||
no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd,
|
||||
"no match ipv6 address prefix-len [(0-128)]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
IPV6_STR
|
||||
"Match prefix length of IPv6 address\n"
|
||||
"Match prefix length of IPv6 address\n"
|
||||
"Prefix length\n")
|
||||
{
|
||||
char *plen = (argc == 6) ? argv[5]->arg : NULL;
|
||||
return zebra_route_match_delete(vty, "ipv6 address prefix-len", plen,
|
||||
RMAP_EVENT_MATCH_DELETED);
|
||||
const char *xpath = "./match-condition[condition='ipv6-prefix-length']";
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (match_ip_nexthop_prefix_len,
|
||||
match_ip_nexthop_prefix_len_cmd,
|
||||
"match ip next-hop prefix-len (0-32)",
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefixlen of nexthop ip address\n"
|
||||
"Match prefixlen of given nexthop\n"
|
||||
"Prefix length\n")
|
||||
DEFPY(
|
||||
match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd,
|
||||
"match ip next-hop prefix-len (0-32)$length",
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefixlen of nexthop IP address\n"
|
||||
"Match prefixlen of given nexthop\n"
|
||||
"Prefix length\n")
|
||||
{
|
||||
return zebra_route_match_add(vty, "ip next-hop prefix-len",
|
||||
argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
|
||||
const char *xpath =
|
||||
"./match-condition[condition='ipv4-next-hop-prefix-length']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:ipv4-prefix-length", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_match_ip_nexthop_prefix_len,
|
||||
no_match_ip_nexthop_prefix_len_cmd,
|
||||
"no match ip next-hop prefix-len [(0-32)]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefixlen of nexthop ip address\n"
|
||||
"Match prefix length of nexthop\n"
|
||||
"Prefix length\n")
|
||||
DEFPY(
|
||||
no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd,
|
||||
"no match ip next-hop prefix-len [(0-32)]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
IP_STR
|
||||
"Match prefixlen of nexthop IP address\n"
|
||||
"Match prefix length of nexthop\n"
|
||||
"Prefix length\n")
|
||||
{
|
||||
char *plen = (argc == 6) ? argv[5]->arg : NULL;
|
||||
return zebra_route_match_delete(vty, "ip next-hop prefix-len", plen,
|
||||
RMAP_EVENT_MATCH_DELETED);
|
||||
const char *xpath =
|
||||
"./match-condition[condition='ipv4-next-hop-prefix-length']";
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (match_source_protocol,
|
||||
match_source_protocol_cmd,
|
||||
"match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
|
||||
MATCH_STR
|
||||
"Match protocol via which the route was learnt\n"
|
||||
"BGP protocol\n"
|
||||
"OSPF protocol\n"
|
||||
"RIP protocol\n"
|
||||
"RIPNG protocol\n"
|
||||
"ISIS protocol\n"
|
||||
"OSPF6 protocol\n"
|
||||
"PIM protocol\n"
|
||||
"NHRP protocol\n"
|
||||
"EIGRP protocol\n"
|
||||
"BABEL protocol\n"
|
||||
"Routes from directly connected peer\n"
|
||||
"Routes from system configuration\n"
|
||||
"Routes from kernel\n"
|
||||
"Statically configured routes\n"
|
||||
"SHARP process\n")
|
||||
DEFPY(
|
||||
match_source_protocol, match_source_protocol_cmd,
|
||||
"match source-protocol " FRR_REDIST_STR_ZEBRA "$proto",
|
||||
MATCH_STR
|
||||
"Match protocol via which the route was learnt\n"
|
||||
FRR_REDIST_HELP_STR_ZEBRA)
|
||||
{
|
||||
char *proto = argv[2]->text;
|
||||
int i;
|
||||
const char *xpath = "./match-condition[condition='source-protocol']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
i = proto_name2num(proto);
|
||||
if (i < 0) {
|
||||
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
return zebra_route_match_add(vty, "source-protocol", proto,
|
||||
RMAP_EVENT_MATCH_ADDED);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:source-protocol", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_match_source_protocol,
|
||||
no_match_source_protocol_cmd,
|
||||
"no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
"No match protocol via which the route was learnt\n"
|
||||
"BGP protocol\n"
|
||||
"OSPF protocol\n"
|
||||
"RIP protocol\n"
|
||||
"RIPNG protocol\n"
|
||||
"ISIS protocol\n"
|
||||
"OSPF6 protocol\n"
|
||||
"PIM protocol\n"
|
||||
"NHRP protocol\n"
|
||||
"EIGRP protocol\n"
|
||||
"BABEL protocol\n"
|
||||
"Routes from directly connected peer\n"
|
||||
"Routes from system configuration\n"
|
||||
"Routes from kernel\n"
|
||||
"Statically configured routes\n"
|
||||
"SHARP process\n")
|
||||
DEFPY(
|
||||
no_match_source_protocol, no_match_source_protocol_cmd,
|
||||
"no match source-protocol [" FRR_REDIST_STR_ZEBRA "]",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
"Match protocol via which the route was learnt\n"
|
||||
FRR_REDIST_HELP_STR_ZEBRA)
|
||||
{
|
||||
char *proto = (argc == 4) ? argv[3]->text : NULL;
|
||||
return zebra_route_match_delete(vty, "source-protocol", proto,
|
||||
RMAP_EVENT_MATCH_DELETED);
|
||||
const char *xpath = "./match-condition[condition='source-protocol']";
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (match_source_instance,
|
||||
match_source_instance_cmd,
|
||||
"match source-instance (0-255)",
|
||||
MATCH_STR
|
||||
"Match the protocol's instance number\n"
|
||||
"The instance number\n")
|
||||
DEFPY(
|
||||
match_source_instance, match_source_instance_cmd,
|
||||
"match source-instance (0-255)$instance",
|
||||
MATCH_STR
|
||||
"Match the protocol's instance number\n"
|
||||
"The instance number\n")
|
||||
{
|
||||
char *instance = argv[2]->arg;
|
||||
const char *xpath = "./match-condition[condition='source-instance']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
return zebra_route_match_add(vty, "source-instance", instance,
|
||||
RMAP_EVENT_MATCH_ADDED);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:source-instance", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, instance_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_match_source_instance,
|
||||
no_match_source_instance_cmd,
|
||||
"no match source-instance [(0-255)]",
|
||||
NO_STR MATCH_STR
|
||||
"Match the protocol's instance number\n"
|
||||
"The instance number\n")
|
||||
DEFPY(
|
||||
no_match_source_instance, no_match_source_instance_cmd,
|
||||
"no match source-instance [(0-255)]",
|
||||
NO_STR MATCH_STR
|
||||
"Match the protocol's instance number\n"
|
||||
"The instance number\n")
|
||||
{
|
||||
char *instance = (argc == 4) ? argv[3]->arg : NULL;
|
||||
const char *xpath = "./match-condition[condition='source-instance']";
|
||||
|
||||
return zebra_route_match_delete(vty, "source-instance", instance,
|
||||
RMAP_EVENT_MATCH_ADDED);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
/* set functions */
|
||||
|
||||
DEFUN (set_src,
|
||||
set_src_cmd,
|
||||
"set src <A.B.C.D|X:X::X:X>",
|
||||
SET_STR
|
||||
"src address for route\n"
|
||||
"IPv4 src address\n"
|
||||
"IPv6 src address\n")
|
||||
DEFPY(
|
||||
set_src, set_src_cmd,
|
||||
"set src <A.B.C.D$addrv4|X:X::X:X$addrv6>",
|
||||
SET_STR
|
||||
"src address for route\n"
|
||||
"IPv4 src address\n"
|
||||
"IPv6 src address\n")
|
||||
{
|
||||
int idx_ip = 2;
|
||||
union g_addr src;
|
||||
struct interface *pif = NULL;
|
||||
int family;
|
||||
struct prefix p;
|
||||
struct vrf *vrf;
|
||||
const char *xpath = "./set-action[action='source']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) {
|
||||
if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1) {
|
||||
vty_out(vty, "%% not a valid IPv4/v6 address\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
p.family = family = AF_INET6;
|
||||
p.u.prefix6 = src.ipv6;
|
||||
p.prefixlen = IPV6_MAX_BITLEN;
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
if (addrv4_str) {
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:source-v4", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
||||
addrv4_str);
|
||||
} else {
|
||||
p.family = family = AF_INET;
|
||||
p.u.prefix4 = src.ipv4;
|
||||
p.prefixlen = IPV4_MAX_BITLEN;
|
||||
snprintf(xpath_value, sizeof(xpath_value),
|
||||
"%s/frr-zebra:source-v6", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
||||
addrv6_str);
|
||||
}
|
||||
|
||||
if (!zebra_check_addr(&p)) {
|
||||
vty_out(vty, "%% not a valid source IPv4/v6 address\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
|
||||
if (family == AF_INET)
|
||||
pif = if_lookup_exact_address((void *)&src.ipv4,
|
||||
AF_INET, vrf->vrf_id);
|
||||
else if (family == AF_INET6)
|
||||
pif = if_lookup_exact_address((void *)&src.ipv6,
|
||||
AF_INET6, vrf->vrf_id);
|
||||
|
||||
if (pif != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pif) {
|
||||
vty_out(vty, "%% not a local address\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
VTY_DECLVAR_CONTEXT(route_map_index, index);
|
||||
return generic_set_add(vty, index, "src", argv[idx_ip]->arg);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_set_src,
|
||||
no_set_src_cmd,
|
||||
"no set src [<A.B.C.D|X:X::X:X>]",
|
||||
NO_STR
|
||||
SET_STR
|
||||
"Source address for route\n"
|
||||
"IPv4 address\n"
|
||||
"IPv6 address\n")
|
||||
DEFPY(
|
||||
no_set_src, no_set_src_cmd,
|
||||
"no set src [<A.B.C.D|X:X::X:X>]",
|
||||
NO_STR
|
||||
SET_STR
|
||||
"Source address for route\n"
|
||||
"IPv4 address\n"
|
||||
"IPv6 address\n")
|
||||
{
|
||||
char *ip = (argc == 4) ? argv[3]->arg : NULL;
|
||||
VTY_DECLVAR_CONTEXT(route_map_index, index);
|
||||
return generic_set_delete(vty, index, "src", ip);
|
||||
const char *xpath = "./set-action[action='source']";
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (zebra_route_map_timer,
|
||||
|
@ -218,6 +218,9 @@ extern void multicast_mode_ipv4_set(enum multicast_mode mode);
|
||||
|
||||
extern enum multicast_mode multicast_mode_ipv4_get(void);
|
||||
|
||||
/* zebra_northbound.c */
|
||||
extern const struct frr_yang_module_info frr_zebra_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user