mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 09:46:54 +00:00
Merge pull request #3548 from opensourcerouting/rip-vrf
rip(ng)d: add VRF support
This commit is contained in:
commit
f61f266a0e
12
lib/if.c
12
lib/if.c
@ -1310,8 +1310,8 @@ static int lib_interface_create(enum nb_event event,
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_interface_delete(enum nb_event event,
|
static int lib_interface_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
@ -1357,8 +1357,8 @@ static int lib_interface_description_modify(enum nb_event event,
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_interface_description_delete(enum nb_event event,
|
static int lib_interface_description_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
@ -1378,13 +1378,13 @@ const struct frr_yang_module_info frr_interface_info = {
|
|||||||
{
|
{
|
||||||
.xpath = "/frr-interface:lib/interface",
|
.xpath = "/frr-interface:lib/interface",
|
||||||
.cbs.create = lib_interface_create,
|
.cbs.create = lib_interface_create,
|
||||||
.cbs.destroy = lib_interface_delete,
|
.cbs.destroy = lib_interface_destroy,
|
||||||
.cbs.cli_show = cli_show_interface,
|
.cbs.cli_show = cli_show_interface,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.xpath = "/frr-interface:lib/interface/description",
|
.xpath = "/frr-interface:lib/interface/description",
|
||||||
.cbs.modify = lib_interface_description_modify,
|
.cbs.modify = lib_interface_description_modify,
|
||||||
.cbs.destroy = lib_interface_description_delete,
|
.cbs.destroy = lib_interface_description_destroy,
|
||||||
.cbs.cli_show = cli_show_interface_desc,
|
.cbs.cli_show = cli_show_interface_desc,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1297,7 +1297,7 @@ DEFPY (show_yang_operational_data,
|
|||||||
yang_dnode_free(dnode);
|
yang_dnode_free(dnode);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
lyd_validate(&dnode, LYD_OPT_DATA | LYD_OPT_DATA_NO_YANGLIB, ly_ctx);
|
lyd_validate(&dnode, LYD_OPT_GET, ly_ctx);
|
||||||
|
|
||||||
/* Display the data. */
|
/* Display the data. */
|
||||||
if (lyd_print_mem(&strp, dnode, format,
|
if (lyd_print_mem(&strp, dnode, format,
|
||||||
|
@ -573,7 +573,7 @@ static int vrf_default_accepts_vrf(int type)
|
|||||||
|
|
||||||
/* Create a socket for the VRF. */
|
/* Create a socket for the VRF. */
|
||||||
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
||||||
char *interfacename)
|
const char *interfacename)
|
||||||
{
|
{
|
||||||
int ret, save_errno, ret2;
|
int ret, save_errno, ret2;
|
||||||
|
|
||||||
@ -944,7 +944,7 @@ vrf_id_t vrf_get_default_id(void)
|
|||||||
return VRF_DEFAULT_INTERNAL;
|
return VRF_DEFAULT_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vrf_bind(vrf_id_t vrf_id, int fd, char *name)
|
int vrf_bind(vrf_id_t vrf_id, int fd, const char *name)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -1003,7 +1003,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
|
int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
|
||||||
char *interfacename)
|
const char *interfacename)
|
||||||
{
|
{
|
||||||
int ret, save_errno, ret2;
|
int ret, save_errno, ret2;
|
||||||
|
|
||||||
|
@ -220,12 +220,12 @@ extern void vrf_terminate(void);
|
|||||||
|
|
||||||
/* Create a socket serving for the given VRF */
|
/* Create a socket serving for the given VRF */
|
||||||
extern int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
extern int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
||||||
char *name);
|
const char *name);
|
||||||
|
|
||||||
extern int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
|
extern int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
|
||||||
char *name);
|
const char *name);
|
||||||
|
|
||||||
extern int vrf_bind(vrf_id_t vrf_id, int fd, char *name);
|
extern int vrf_bind(vrf_id_t vrf_id, int fd, const char *name);
|
||||||
|
|
||||||
/* VRF ioctl operations */
|
/* VRF ioctl operations */
|
||||||
extern int vrf_getaddrinfo(const char *node, const char *service,
|
extern int vrf_getaddrinfo(const char *node, const char *service,
|
||||||
|
19
lib/yang.c
19
lib/yang.c
@ -610,6 +610,25 @@ struct list *yang_data_list_new(void)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct yang_data *yang_data_list_find(const struct list *list,
|
||||||
|
const char *xpath_fmt, ...)
|
||||||
|
{
|
||||||
|
char xpath[XPATH_MAXLEN];
|
||||||
|
struct yang_data *data;
|
||||||
|
struct listnode *node;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, xpath_fmt);
|
||||||
|
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(list, node, data))
|
||||||
|
if (strmatch(data->xpath, xpath))
|
||||||
|
return data;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void *ly_dup_cb(const void *priv)
|
static void *ly_dup_cb(const void *priv)
|
||||||
{
|
{
|
||||||
/* Make a shallow copy of the priv pointer. */
|
/* Make a shallow copy of the priv pointer. */
|
||||||
|
15
lib/yang.h
15
lib/yang.h
@ -513,6 +513,21 @@ extern void yang_data_free(struct yang_data *data);
|
|||||||
*/
|
*/
|
||||||
extern struct list *yang_data_list_new(void);
|
extern struct list *yang_data_list_new(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the yang_data structure corresponding to an XPath in a list.
|
||||||
|
*
|
||||||
|
* list
|
||||||
|
* list of yang_data structures to operate on.
|
||||||
|
*
|
||||||
|
* xpath_fmt
|
||||||
|
* XPath to search for (format string).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Pointer to yang_data if found, NULL otherwise.
|
||||||
|
*/
|
||||||
|
extern struct yang_data *yang_data_list_find(const struct list *list,
|
||||||
|
const char *xpath_fmt, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create and set up a libyang context (for use by the translator)
|
* Create and set up a libyang context (for use by the translator)
|
||||||
*/
|
*/
|
||||||
|
@ -39,31 +39,46 @@
|
|||||||
*/
|
*/
|
||||||
DEFPY_NOSH (router_rip,
|
DEFPY_NOSH (router_rip,
|
||||||
router_rip_cmd,
|
router_rip_cmd,
|
||||||
"router rip",
|
"router rip [vrf NAME]",
|
||||||
"Enable a routing process\n"
|
"Enable a routing process\n"
|
||||||
"Routing Information Protocol (RIP)\n")
|
"Routing Information Protocol (RIP)\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
|
char xpath[XPATH_MAXLEN];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
nb_cli_enqueue_change(vty, "/frr-ripd:ripd/instance", NB_OP_CREATE,
|
/* Build RIP instance XPath. */
|
||||||
NULL);
|
if (!vrf)
|
||||||
|
vrf = VRF_DEFAULT_NAME;
|
||||||
|
snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
|
||||||
|
vrf);
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||||
|
|
||||||
ret = nb_cli_apply_changes(vty, NULL);
|
ret = nb_cli_apply_changes(vty, NULL);
|
||||||
if (ret == CMD_SUCCESS)
|
if (ret == CMD_SUCCESS)
|
||||||
VTY_PUSH_XPATH(RIP_NODE, "/frr-ripd:ripd/instance");
|
VTY_PUSH_XPATH(RIP_NODE, xpath);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFPY (no_router_rip,
|
DEFPY (no_router_rip,
|
||||||
no_router_rip_cmd,
|
no_router_rip_cmd,
|
||||||
"no router rip",
|
"no router rip [vrf NAME]",
|
||||||
NO_STR
|
NO_STR
|
||||||
"Enable a routing process\n"
|
"Enable a routing process\n"
|
||||||
"Routing Information Protocol (RIP)\n")
|
"Routing Information Protocol (RIP)\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
nb_cli_enqueue_change(vty, "/frr-ripd:ripd/instance", NB_OP_DESTROY,
|
char xpath[XPATH_MAXLEN];
|
||||||
NULL);
|
|
||||||
|
/* Build RIP instance XPath. */
|
||||||
|
if (!vrf)
|
||||||
|
vrf = VRF_DEFAULT_NAME;
|
||||||
|
snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
|
||||||
|
vrf);
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||||
|
|
||||||
return nb_cli_apply_changes(vty, NULL);
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
}
|
}
|
||||||
@ -71,8 +86,15 @@ DEFPY (no_router_rip,
|
|||||||
void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults)
|
bool show_defaults)
|
||||||
{
|
{
|
||||||
|
const char *vrf_name;
|
||||||
|
|
||||||
|
vrf_name = yang_dnode_get_string(dnode, "./vrf");
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_out(vty, "!\n");
|
||||||
vty_out(vty, "router rip\n");
|
vty_out(vty, "router rip");
|
||||||
|
if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
|
||||||
|
vty_out(vty, " vrf %s", vrf_name);
|
||||||
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -902,7 +924,7 @@ DEFPY (no_ip_rip_authentication_string,
|
|||||||
"Authentication string\n"
|
"Authentication string\n"
|
||||||
"Authentication string\n")
|
"Authentication string\n")
|
||||||
{
|
{
|
||||||
nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_MODIFY,
|
nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DESTROY,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return nb_cli_apply_changes(vty, "./frr-ripd:rip");
|
return nb_cli_apply_changes(vty, "./frr-ripd:rip");
|
||||||
@ -970,12 +992,24 @@ void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
|
|||||||
*/
|
*/
|
||||||
DEFPY (clear_ip_rip,
|
DEFPY (clear_ip_rip,
|
||||||
clear_ip_rip_cmd,
|
clear_ip_rip_cmd,
|
||||||
"clear ip rip",
|
"clear ip rip [vrf WORD]",
|
||||||
CLEAR_STR
|
CLEAR_STR
|
||||||
IP_STR
|
IP_STR
|
||||||
"Clear IP RIP database\n")
|
"Clear IP RIP database\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
return nb_cli_rpc("/frr-ripd:clear-rip-route", NULL, NULL);
|
struct list *input;
|
||||||
|
|
||||||
|
input = list_new();
|
||||||
|
if (vrf) {
|
||||||
|
struct yang_data *yang_vrf;
|
||||||
|
|
||||||
|
yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf",
|
||||||
|
vrf);
|
||||||
|
listnode_add(input, yang_vrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nb_cli_rpc("/frr-ripd:clear-rip-route", input, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_cli_init(void)
|
void rip_cli_init(void)
|
||||||
|
@ -50,9 +50,9 @@ DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
|
|||||||
static void rip_enable_apply(struct interface *);
|
static void rip_enable_apply(struct interface *);
|
||||||
static void rip_passive_interface_apply(struct interface *);
|
static void rip_passive_interface_apply(struct interface *);
|
||||||
static int rip_if_down(struct interface *ifp);
|
static int rip_if_down(struct interface *ifp);
|
||||||
static int rip_enable_if_lookup(const char *ifname);
|
static int rip_enable_if_lookup(struct rip *rip, const char *ifname);
|
||||||
static int rip_enable_network_lookup2(struct connected *connected);
|
static int rip_enable_network_lookup2(struct connected *connected);
|
||||||
static void rip_enable_apply_all(void);
|
static void rip_enable_apply_all(struct rip *rip);
|
||||||
|
|
||||||
const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"},
|
const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"},
|
||||||
{RI_RIP_VERSION_2, "2"},
|
{RI_RIP_VERSION_2, "2"},
|
||||||
@ -60,15 +60,6 @@ const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"},
|
|||||||
{RI_RIP_VERSION_NONE, "none"},
|
{RI_RIP_VERSION_NONE, "none"},
|
||||||
{0}};
|
{0}};
|
||||||
|
|
||||||
/* RIP enabled network vector. */
|
|
||||||
vector rip_enable_interface;
|
|
||||||
|
|
||||||
/* RIP enabled interface table. */
|
|
||||||
struct route_table *rip_enable_network;
|
|
||||||
|
|
||||||
/* Vector to store passive-interface name. */
|
|
||||||
vector Vrip_passive_nondefault;
|
|
||||||
|
|
||||||
/* Join to the RIP version 2 multicast group. */
|
/* Join to the RIP version 2 multicast group. */
|
||||||
static int ipv4_multicast_join(int sock, struct in_addr group,
|
static int ipv4_multicast_join(int sock, struct in_addr group,
|
||||||
struct in_addr ifa, ifindex_t ifindex)
|
struct in_addr ifa, ifindex_t ifindex)
|
||||||
@ -208,7 +199,7 @@ static void rip_request_interface(struct interface *ifp)
|
|||||||
|
|
||||||
/* If there is no version configuration in the interface,
|
/* If there is no version configuration in the interface,
|
||||||
use rip's version setting. */
|
use rip's version setting. */
|
||||||
vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send
|
vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? ri->rip->version_send
|
||||||
: ri->ri_send);
|
: ri->ri_send);
|
||||||
if (vsend & RIPv1)
|
if (vsend & RIPv1)
|
||||||
rip_request_interface_send(ifp, RIPv1);
|
rip_request_interface_send(ifp, RIPv1);
|
||||||
@ -329,12 +320,11 @@ static int rip_if_ipv4_address_check(struct interface *ifp)
|
|||||||
|
|
||||||
|
|
||||||
/* Does this address belongs to me ? */
|
/* Does this address belongs to me ? */
|
||||||
int if_check_address(struct in_addr addr)
|
int if_check_address(struct rip *rip, struct in_addr addr)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp) {
|
FOR_ALL_INTERFACES (rip->vrf, ifp) {
|
||||||
struct listnode *cnode;
|
struct listnode *cnode;
|
||||||
struct connected *connected;
|
struct connected *connected;
|
||||||
|
|
||||||
@ -369,13 +359,14 @@ int rip_interface_down(int command, struct zclient *zclient,
|
|||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
rip_interface_sync(ifp);
|
||||||
rip_if_down(ifp);
|
rip_if_down(ifp);
|
||||||
|
|
||||||
if (IS_RIP_DEBUG_ZEBRA)
|
if (IS_RIP_DEBUG_ZEBRA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"interface %s index %d flags %llx metric %d mtu %d is down",
|
"interface %s vrf %u index %d flags %llx metric %d mtu %d is down",
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
ifp->metric, ifp->mtu);
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -395,9 +386,11 @@ int rip_interface_up(int command, struct zclient *zclient, zebra_size_t length,
|
|||||||
|
|
||||||
if (IS_RIP_DEBUG_ZEBRA)
|
if (IS_RIP_DEBUG_ZEBRA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"interface %s index %d flags %#llx metric %d mtu %d is up",
|
"interface %s vrf %u index %d flags %#llx metric %d mtu %d is up",
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
ifp->metric, ifp->mtu);
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
||||||
|
|
||||||
|
rip_interface_sync(ifp);
|
||||||
|
|
||||||
/* Check if this interface is RIP enabled or not.*/
|
/* Check if this interface is RIP enabled or not.*/
|
||||||
rip_enable_apply(ifp);
|
rip_enable_apply(ifp);
|
||||||
@ -418,12 +411,13 @@ int rip_interface_add(int command, struct zclient *zclient, zebra_size_t length,
|
|||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
|
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
|
||||||
|
rip_interface_sync(ifp);
|
||||||
|
|
||||||
if (IS_RIP_DEBUG_ZEBRA)
|
if (IS_RIP_DEBUG_ZEBRA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"interface add %s index %d flags %#llx metric %d mtu %d",
|
"interface add %s vrf %u index %d flags %#llx metric %d mtu %d",
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
ifp->metric, ifp->mtu);
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
||||||
|
|
||||||
/* Check if this interface is RIP enabled or not.*/
|
/* Check if this interface is RIP enabled or not.*/
|
||||||
rip_enable_apply(ifp);
|
rip_enable_apply(ifp);
|
||||||
@ -456,13 +450,15 @@ int rip_interface_delete(int command, struct zclient *zclient,
|
|||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
rip_interface_sync(ifp);
|
||||||
if (if_is_up(ifp)) {
|
if (if_is_up(ifp)) {
|
||||||
rip_if_down(ifp);
|
rip_if_down(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
|
zlog_info(
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
"interface delete %s vrf %u index %d flags %#llx metric %d mtu %d",
|
||||||
ifp->metric, ifp->mtu);
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
||||||
|
|
||||||
/* To support pseudo interface do not free interface structure. */
|
/* To support pseudo interface do not free interface structure. */
|
||||||
/* if_delete(ifp); */
|
/* if_delete(ifp); */
|
||||||
@ -471,6 +467,28 @@ int rip_interface_delete(int command, struct zclient *zclient,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* VRF update for an interface. */
|
||||||
|
int rip_interface_vrf_update(int command, struct zclient *zclient,
|
||||||
|
zebra_size_t length, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
vrf_id_t new_vrf_id;
|
||||||
|
|
||||||
|
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
|
||||||
|
&new_vrf_id);
|
||||||
|
if (!ifp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (IS_RIP_DEBUG_ZEBRA)
|
||||||
|
zlog_debug("interface %s VRF change vrf_id %u new vrf id %u",
|
||||||
|
ifp->name, vrf_id, new_vrf_id);
|
||||||
|
|
||||||
|
if_update_to_new_vrf(ifp, new_vrf_id);
|
||||||
|
rip_interface_sync(ifp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void rip_interface_clean(struct rip_interface *ri)
|
static void rip_interface_clean(struct rip_interface *ri)
|
||||||
{
|
{
|
||||||
ri->enable_network = 0;
|
ri->enable_network = 0;
|
||||||
@ -483,12 +501,11 @@ static void rip_interface_clean(struct rip_interface *ri)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_interfaces_clean(void)
|
void rip_interfaces_clean(struct rip *rip)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
FOR_ALL_INTERFACES (rip->vrf, ifp)
|
||||||
rip_interface_clean(ifp->info);
|
rip_interface_clean(ifp->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,20 +548,22 @@ static void rip_interface_reset(struct rip_interface *ri)
|
|||||||
|
|
||||||
int rip_if_down(struct interface *ifp)
|
int rip_if_down(struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
struct rip *rip;
|
||||||
struct route_node *rp;
|
struct route_node *rp;
|
||||||
struct rip_info *rinfo;
|
struct rip_info *rinfo;
|
||||||
struct rip_interface *ri = NULL;
|
struct rip_interface *ri = NULL;
|
||||||
struct list *list = NULL;
|
struct list *list = NULL;
|
||||||
struct listnode *listnode = NULL, *nextnode = NULL;
|
struct listnode *listnode = NULL, *nextnode = NULL;
|
||||||
|
|
||||||
|
ri = ifp->info;
|
||||||
|
rip = ri->rip;
|
||||||
if (rip) {
|
if (rip) {
|
||||||
for (rp = route_top(rip->table); rp; rp = route_next(rp))
|
for (rp = route_top(rip->table); rp; rp = route_next(rp))
|
||||||
if ((list = rp->info) != NULL)
|
if ((list = rp->info) != NULL)
|
||||||
for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
|
for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
|
||||||
rinfo))
|
rinfo))
|
||||||
if (rinfo->nh.ifindex == ifp->ifindex)
|
if (rinfo->nh.ifindex == ifp->ifindex)
|
||||||
rip_ecmp_delete(rinfo);
|
rip_ecmp_delete(rip, rinfo);
|
||||||
|
|
||||||
ri = ifp->info;
|
|
||||||
|
|
||||||
if (ri->running) {
|
if (ri->running) {
|
||||||
if (IS_RIP_DEBUG_EVENT)
|
if (IS_RIP_DEBUG_EVENT)
|
||||||
@ -560,18 +579,10 @@ int rip_if_down(struct interface *ifp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Needed for stop RIP process. */
|
|
||||||
void rip_if_down_all(void)
|
|
||||||
{
|
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
|
||||||
rip_if_down(ifp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rip_apply_address_add(struct connected *ifc)
|
static void rip_apply_address_add(struct connected *ifc)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = ifc->ifp->info;
|
||||||
|
struct rip *rip = ri->rip;
|
||||||
struct prefix_ipv4 address;
|
struct prefix_ipv4 address;
|
||||||
struct nexthop nh;
|
struct nexthop nh;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
@ -597,10 +608,11 @@ static void rip_apply_address_add(struct connected *ifc)
|
|||||||
|
|
||||||
/* Check if this interface is RIP enabled or not
|
/* Check if this interface is RIP enabled or not
|
||||||
or Check if this address's prefix is RIP enabled */
|
or Check if this address's prefix is RIP enabled */
|
||||||
if ((rip_enable_if_lookup(ifc->ifp->name) >= 0)
|
if ((rip_enable_if_lookup(rip, ifc->ifp->name) >= 0)
|
||||||
|| (rip_enable_network_lookup2(ifc) >= 0))
|
|| (rip_enable_network_lookup2(ifc) >= 0))
|
||||||
rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
|
rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT,
|
||||||
&address, &nh, 0, 0, 0);
|
RIP_ROUTE_INTERFACE, &address, &nh, 0, 0,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rip_interface_address_add(int command, struct zclient *zclient,
|
int rip_interface_address_add(int command, struct zclient *zclient,
|
||||||
@ -634,6 +646,8 @@ int rip_interface_address_add(int command, struct zclient *zclient,
|
|||||||
|
|
||||||
static void rip_apply_address_del(struct connected *ifc)
|
static void rip_apply_address_del(struct connected *ifc)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = ifc->ifp->info;
|
||||||
|
struct rip *rip = ri->rip;
|
||||||
struct prefix_ipv4 address;
|
struct prefix_ipv4 address;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
|
||||||
@ -651,7 +665,7 @@ static void rip_apply_address_del(struct connected *ifc)
|
|||||||
address.prefixlen = p->prefixlen;
|
address.prefixlen = p->prefixlen;
|
||||||
apply_mask_ipv4(&address);
|
apply_mask_ipv4(&address);
|
||||||
|
|
||||||
rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
|
rip_redistribute_delete(rip, ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
|
||||||
&address, ifc->ifp->ifindex);
|
&address, ifc->ifp->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,10 +703,15 @@ int rip_interface_address_delete(int command, struct zclient *zclient,
|
|||||||
* is within the ripng_enable_network table. */
|
* is within the ripng_enable_network table. */
|
||||||
static int rip_enable_network_lookup_if(struct interface *ifp)
|
static int rip_enable_network_lookup_if(struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = ifp->info;
|
||||||
|
struct rip *rip = ri->rip;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct connected *connected;
|
struct connected *connected;
|
||||||
struct prefix_ipv4 address;
|
struct prefix_ipv4 address;
|
||||||
|
|
||||||
|
if (!rip)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
|
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
struct route_node *n;
|
struct route_node *n;
|
||||||
@ -704,7 +723,7 @@ static int rip_enable_network_lookup_if(struct interface *ifp)
|
|||||||
address.prefix = p->u.prefix4;
|
address.prefix = p->u.prefix4;
|
||||||
address.prefixlen = IPV4_MAX_BITLEN;
|
address.prefixlen = IPV4_MAX_BITLEN;
|
||||||
|
|
||||||
n = route_node_match(rip_enable_network,
|
n = route_node_match(rip->enable_network,
|
||||||
(struct prefix *)&address);
|
(struct prefix *)&address);
|
||||||
if (n) {
|
if (n) {
|
||||||
route_unlock_node(n);
|
route_unlock_node(n);
|
||||||
@ -716,8 +735,10 @@ static int rip_enable_network_lookup_if(struct interface *ifp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check wether connected is within the ripng_enable_network table. */
|
/* Check wether connected is within the ripng_enable_network table. */
|
||||||
int rip_enable_network_lookup2(struct connected *connected)
|
static int rip_enable_network_lookup2(struct connected *connected)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = connected->ifp->info;
|
||||||
|
struct rip *rip = ri->rip;
|
||||||
struct prefix_ipv4 address;
|
struct prefix_ipv4 address;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
|
||||||
@ -731,8 +752,8 @@ int rip_enable_network_lookup2(struct connected *connected)
|
|||||||
address.prefixlen = IPV4_MAX_BITLEN;
|
address.prefixlen = IPV4_MAX_BITLEN;
|
||||||
|
|
||||||
/* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within
|
/* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within
|
||||||
* rip_enable_network */
|
* rip->enable_network */
|
||||||
node = route_node_match(rip_enable_network,
|
node = route_node_match(rip->enable_network,
|
||||||
(struct prefix *)&address);
|
(struct prefix *)&address);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
@ -744,11 +765,11 @@ int rip_enable_network_lookup2(struct connected *connected)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Add RIP enable network. */
|
/* Add RIP enable network. */
|
||||||
int rip_enable_network_add(struct prefix *p)
|
int rip_enable_network_add(struct rip *rip, struct prefix *p)
|
||||||
{
|
{
|
||||||
struct route_node *node;
|
struct route_node *node;
|
||||||
|
|
||||||
node = route_node_get(rip_enable_network, p);
|
node = route_node_get(rip->enable_network, p);
|
||||||
|
|
||||||
if (node->info) {
|
if (node->info) {
|
||||||
route_unlock_node(node);
|
route_unlock_node(node);
|
||||||
@ -757,17 +778,17 @@ int rip_enable_network_add(struct prefix *p)
|
|||||||
node->info = (void *)1;
|
node->info = (void *)1;
|
||||||
|
|
||||||
/* XXX: One should find a better solution than a generic one */
|
/* XXX: One should find a better solution than a generic one */
|
||||||
rip_enable_apply_all();
|
rip_enable_apply_all(rip);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete RIP enable network. */
|
/* Delete RIP enable network. */
|
||||||
int rip_enable_network_delete(struct prefix *p)
|
int rip_enable_network_delete(struct rip *rip, struct prefix *p)
|
||||||
{
|
{
|
||||||
struct route_node *node;
|
struct route_node *node;
|
||||||
|
|
||||||
node = route_node_lookup(rip_enable_network, p);
|
node = route_node_lookup(rip->enable_network, p);
|
||||||
if (node) {
|
if (node) {
|
||||||
node->info = NULL;
|
node->info = NULL;
|
||||||
|
|
||||||
@ -778,7 +799,7 @@ int rip_enable_network_delete(struct prefix *p)
|
|||||||
route_unlock_node(node);
|
route_unlock_node(node);
|
||||||
|
|
||||||
/* XXX: One should find a better solution than a generic one */
|
/* XXX: One should find a better solution than a generic one */
|
||||||
rip_enable_apply_all();
|
rip_enable_apply_all(rip);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -787,50 +808,53 @@ int rip_enable_network_delete(struct prefix *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check interface is enabled by ifname statement. */
|
/* Check interface is enabled by ifname statement. */
|
||||||
static int rip_enable_if_lookup(const char *ifname)
|
static int rip_enable_if_lookup(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for (i = 0; i < vector_active(rip_enable_interface); i++)
|
if (!rip)
|
||||||
if ((str = vector_slot(rip_enable_interface, i)) != NULL)
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < vector_active(rip->enable_interface); i++)
|
||||||
|
if ((str = vector_slot(rip->enable_interface, i)) != NULL)
|
||||||
if (strcmp(str, ifname) == 0)
|
if (strcmp(str, ifname) == 0)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add interface to rip_enable_if. */
|
/* Add interface to rip_enable_if. */
|
||||||
int rip_enable_if_add(const char *ifname)
|
int rip_enable_if_add(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rip_enable_if_lookup(ifname);
|
ret = rip_enable_if_lookup(rip, ifname);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
return NB_ERR_INCONSISTENCY;
|
return NB_ERR_INCONSISTENCY;
|
||||||
|
|
||||||
vector_set(rip_enable_interface,
|
vector_set(rip->enable_interface,
|
||||||
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
|
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
|
||||||
|
|
||||||
rip_enable_apply_all(); /* TODOVJ */
|
rip_enable_apply_all(rip); /* TODOVJ */
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete interface from rip_enable_if. */
|
/* Delete interface from rip_enable_if. */
|
||||||
int rip_enable_if_delete(const char *ifname)
|
int rip_enable_if_delete(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
index = rip_enable_if_lookup(ifname);
|
index = rip_enable_if_lookup(rip, ifname);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return NB_ERR_INCONSISTENCY;
|
return NB_ERR_INCONSISTENCY;
|
||||||
|
|
||||||
str = vector_slot(rip_enable_interface, index);
|
str = vector_slot(rip->enable_interface, index);
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
||||||
vector_unset(rip_enable_interface, index);
|
vector_unset(rip->enable_interface, index);
|
||||||
|
|
||||||
rip_enable_apply_all(); /* TODOVJ */
|
rip_enable_apply_all(rip); /* TODOVJ */
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -848,7 +872,7 @@ static int rip_interface_wakeup(struct thread *t)
|
|||||||
ri->t_wakeup = NULL;
|
ri->t_wakeup = NULL;
|
||||||
|
|
||||||
/* Join to multicast group. */
|
/* Join to multicast group. */
|
||||||
if (rip_multicast_join(ifp, rip->sock) < 0) {
|
if (rip_multicast_join(ifp, ri->rip->sock) < 0) {
|
||||||
flog_err_sys(EC_LIB_SOCKET,
|
flog_err_sys(EC_LIB_SOCKET,
|
||||||
"multicast join failed, interface %s not running",
|
"multicast join failed, interface %s not running",
|
||||||
ifp->name);
|
ifp->name);
|
||||||
@ -866,6 +890,8 @@ static int rip_interface_wakeup(struct thread *t)
|
|||||||
|
|
||||||
static void rip_connect_set(struct interface *ifp, int set)
|
static void rip_connect_set(struct interface *ifp, int set)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = ifp->info;
|
||||||
|
struct rip *rip = ri->rip;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct connected *connected;
|
struct connected *connected;
|
||||||
struct prefix_ipv4 address;
|
struct prefix_ipv4 address;
|
||||||
@ -890,17 +916,18 @@ static void rip_connect_set(struct interface *ifp, int set)
|
|||||||
if (set) {
|
if (set) {
|
||||||
/* Check once more wether this prefix is within a
|
/* Check once more wether this prefix is within a
|
||||||
* "network IF_OR_PREF" one */
|
* "network IF_OR_PREF" one */
|
||||||
if ((rip_enable_if_lookup(connected->ifp->name) >= 0)
|
if ((rip_enable_if_lookup(rip, connected->ifp->name)
|
||||||
|
>= 0)
|
||||||
|| (rip_enable_network_lookup2(connected) >= 0))
|
|| (rip_enable_network_lookup2(connected) >= 0))
|
||||||
rip_redistribute_add(ZEBRA_ROUTE_CONNECT,
|
rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT,
|
||||||
RIP_ROUTE_INTERFACE,
|
RIP_ROUTE_INTERFACE,
|
||||||
&address, &nh, 0, 0, 0);
|
&address, &nh, 0, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
rip_redistribute_delete(ZEBRA_ROUTE_CONNECT,
|
rip_redistribute_delete(rip, ZEBRA_ROUTE_CONNECT,
|
||||||
RIP_ROUTE_INTERFACE, &address,
|
RIP_ROUTE_INTERFACE, &address,
|
||||||
connected->ifp->ifindex);
|
connected->ifp->ifindex);
|
||||||
if (rip_redistribute_check(ZEBRA_ROUTE_CONNECT))
|
if (rip_redistribute_check(rip, ZEBRA_ROUTE_CONNECT))
|
||||||
rip_redistribute_add(ZEBRA_ROUTE_CONNECT,
|
rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT,
|
||||||
RIP_ROUTE_REDISTRIBUTE,
|
RIP_ROUTE_REDISTRIBUTE,
|
||||||
&address, &nh, 0, 0, 0);
|
&address, &nh, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@ -929,7 +956,7 @@ void rip_enable_apply(struct interface *ifp)
|
|||||||
ri->enable_network = 0;
|
ri->enable_network = 0;
|
||||||
|
|
||||||
/* Check interface name configuration. */
|
/* Check interface name configuration. */
|
||||||
ret = rip_enable_if_lookup(ifp->name);
|
ret = rip_enable_if_lookup(ri->rip, ifp->name);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
ri->enable_interface = 1;
|
ri->enable_interface = 1;
|
||||||
else
|
else
|
||||||
@ -962,17 +989,16 @@ void rip_enable_apply(struct interface *ifp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Apply network configuration to all interface. */
|
/* Apply network configuration to all interface. */
|
||||||
void rip_enable_apply_all(void)
|
static void rip_enable_apply_all(struct rip *rip)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
/* Check each interface. */
|
/* Check each interface. */
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
FOR_ALL_INTERFACES (rip->vrf, ifp)
|
||||||
rip_enable_apply(ifp);
|
rip_enable_apply(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rip_neighbor_lookup(struct sockaddr_in *from)
|
int rip_neighbor_lookup(struct rip *rip, struct sockaddr_in *from)
|
||||||
{
|
{
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
struct route_node *node;
|
struct route_node *node;
|
||||||
@ -991,7 +1017,7 @@ int rip_neighbor_lookup(struct sockaddr_in *from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new RIP neighbor to the neighbor tree. */
|
/* Add new RIP neighbor to the neighbor tree. */
|
||||||
int rip_neighbor_add(struct prefix_ipv4 *p)
|
int rip_neighbor_add(struct rip *rip, struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct route_node *node;
|
struct route_node *node;
|
||||||
|
|
||||||
@ -1006,7 +1032,7 @@ int rip_neighbor_add(struct prefix_ipv4 *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Delete RIP neighbor from the neighbor tree. */
|
/* Delete RIP neighbor from the neighbor tree. */
|
||||||
int rip_neighbor_delete(struct prefix_ipv4 *p)
|
int rip_neighbor_delete(struct rip *rip, struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct route_node *node;
|
struct route_node *node;
|
||||||
|
|
||||||
@ -1027,50 +1053,51 @@ int rip_neighbor_delete(struct prefix_ipv4 *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clear all network and neighbor configuration. */
|
/* Clear all network and neighbor configuration. */
|
||||||
void rip_clean_network(void)
|
void rip_clean_network(struct rip *rip)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
|
||||||
/* rip_enable_network. */
|
/* rip->enable_network. */
|
||||||
for (rn = route_top(rip_enable_network); rn; rn = route_next(rn))
|
for (rn = route_top(rip->enable_network); rn; rn = route_next(rn))
|
||||||
if (rn->info) {
|
if (rn->info) {
|
||||||
rn->info = NULL;
|
rn->info = NULL;
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rip_enable_interface. */
|
/* rip->enable_interface. */
|
||||||
for (i = 0; i < vector_active(rip_enable_interface); i++)
|
for (i = 0; i < vector_active(rip->enable_interface); i++)
|
||||||
if ((str = vector_slot(rip_enable_interface, i)) != NULL) {
|
if ((str = vector_slot(rip->enable_interface, i)) != NULL) {
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
||||||
vector_slot(rip_enable_interface, i) = NULL;
|
vector_slot(rip->enable_interface, i) = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utility function for looking up passive interface settings. */
|
/* Utility function for looking up passive interface settings. */
|
||||||
static int rip_passive_nondefault_lookup(const char *ifname)
|
static int rip_passive_nondefault_lookup(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
|
for (i = 0; i < vector_active(rip->passive_nondefault); i++)
|
||||||
if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL)
|
if ((str = vector_slot(rip->passive_nondefault, i)) != NULL)
|
||||||
if (strcmp(str, ifname) == 0)
|
if (strcmp(str, ifname) == 0)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_passive_interface_apply(struct interface *ifp)
|
static void rip_passive_interface_apply(struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
struct rip *rip;
|
||||||
struct rip_interface *ri;
|
struct rip_interface *ri;
|
||||||
|
|
||||||
|
ri = ifp->info;
|
||||||
|
rip = ri->rip;
|
||||||
if (rip == NULL)
|
if (rip == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ri = ifp->info;
|
ri->passive = ((rip_passive_nondefault_lookup(rip, ifp->name) < 0)
|
||||||
|
|
||||||
ri->passive = ((rip_passive_nondefault_lookup(ifp->name) < 0)
|
|
||||||
? rip->passive_default
|
? rip->passive_default
|
||||||
: !rip->passive_default);
|
: !rip->passive_default);
|
||||||
|
|
||||||
@ -1079,39 +1106,38 @@ void rip_passive_interface_apply(struct interface *ifp)
|
|||||||
ri->passive);
|
ri->passive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rip_passive_interface_apply_all(void)
|
static void rip_passive_interface_apply_all(struct rip *rip)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
FOR_ALL_INTERFACES (rip->vrf, ifp)
|
||||||
rip_passive_interface_apply(ifp);
|
rip_passive_interface_apply(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Passive interface. */
|
/* Passive interface. */
|
||||||
int rip_passive_nondefault_set(const char *ifname)
|
int rip_passive_nondefault_set(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
if (rip_passive_nondefault_lookup(ifname) >= 0)
|
if (rip_passive_nondefault_lookup(rip, ifname) >= 0)
|
||||||
/*
|
/*
|
||||||
* Don't return an error, this can happen after changing
|
* Don't return an error, this can happen after changing
|
||||||
* 'passive-default'.
|
* 'passive-default'.
|
||||||
*/
|
*/
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
vector_set(Vrip_passive_nondefault,
|
vector_set(rip->passive_nondefault,
|
||||||
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
|
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
|
||||||
|
|
||||||
rip_passive_interface_apply_all();
|
rip_passive_interface_apply_all(rip);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rip_passive_nondefault_unset(const char *ifname)
|
int rip_passive_nondefault_unset(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
i = rip_passive_nondefault_lookup(ifname);
|
i = rip_passive_nondefault_lookup(rip, ifname);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
/*
|
/*
|
||||||
* Don't return an error, this can happen after changing
|
* Don't return an error, this can happen after changing
|
||||||
@ -1119,61 +1145,64 @@ int rip_passive_nondefault_unset(const char *ifname)
|
|||||||
*/
|
*/
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
str = vector_slot(Vrip_passive_nondefault, i);
|
str = vector_slot(rip->passive_nondefault, i);
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
||||||
vector_unset(Vrip_passive_nondefault, i);
|
vector_unset(rip->passive_nondefault, i);
|
||||||
|
|
||||||
rip_passive_interface_apply_all();
|
rip_passive_interface_apply_all(rip);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free all configured RIP passive-interface settings. */
|
/* Free all configured RIP passive-interface settings. */
|
||||||
void rip_passive_nondefault_clean(void)
|
void rip_passive_nondefault_clean(struct rip *rip)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
|
for (i = 0; i < vector_active(rip->passive_nondefault); i++)
|
||||||
if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL) {
|
if ((str = vector_slot(rip->passive_nondefault, i)) != NULL) {
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
||||||
vector_slot(Vrip_passive_nondefault, i) = NULL;
|
vector_slot(rip->passive_nondefault, i) = NULL;
|
||||||
}
|
}
|
||||||
rip_passive_interface_apply_all();
|
rip_passive_interface_apply_all(rip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write rip configuration of each interface. */
|
/* Write rip configuration of each interface. */
|
||||||
static int rip_interface_config_write(struct vty *vty)
|
static int rip_interface_config_write(struct vty *vty)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
struct vrf *vrf;
|
||||||
struct interface *ifp;
|
|
||||||
int write = 0;
|
int write = 0;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||||
struct lyd_node *dnode;
|
struct interface *ifp;
|
||||||
|
|
||||||
dnode = yang_dnode_get(
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
||||||
running_config->dnode,
|
struct lyd_node *dnode;
|
||||||
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
|
|
||||||
ifp->name, vrf->name);
|
|
||||||
if (dnode == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
write = 1;
|
dnode = yang_dnode_get(
|
||||||
nb_cli_show_dnode_cmds(vty, dnode, false);
|
running_config->dnode,
|
||||||
|
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
|
||||||
|
ifp->name, vrf->name);
|
||||||
|
if (dnode == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
write = 1;
|
||||||
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rip_show_network_config(struct vty *vty)
|
int rip_show_network_config(struct vty *vty, struct rip *rip)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
struct route_node *node;
|
struct route_node *node;
|
||||||
|
|
||||||
/* Network type RIP enable interface statement. */
|
/* Network type RIP enable interface statement. */
|
||||||
for (node = route_top(rip_enable_network); node;
|
for (node = route_top(rip->enable_network); node;
|
||||||
node = route_next(node))
|
node = route_next(node))
|
||||||
if (node->info)
|
if (node->info)
|
||||||
vty_out(vty, " %s/%u\n",
|
vty_out(vty, " %s/%u\n",
|
||||||
@ -1181,8 +1210,8 @@ int rip_show_network_config(struct vty *vty)
|
|||||||
node->p.prefixlen);
|
node->p.prefixlen);
|
||||||
|
|
||||||
/* Interface name RIP enable statement. */
|
/* Interface name RIP enable statement. */
|
||||||
for (i = 0; i < vector_active(rip_enable_interface); i++)
|
for (i = 0; i < vector_active(rip->enable_interface); i++)
|
||||||
if ((ifname = vector_slot(rip_enable_interface, i)) != NULL)
|
if ((ifname = vector_slot(rip->enable_interface, i)) != NULL)
|
||||||
vty_out(vty, " %s\n", ifname);
|
vty_out(vty, " %s\n", ifname);
|
||||||
|
|
||||||
/* RIP neighbors listing. */
|
/* RIP neighbors listing. */
|
||||||
@ -1197,10 +1226,26 @@ static struct cmd_node interface_node = {
|
|||||||
INTERFACE_NODE, "%s(config-if)# ", 1,
|
INTERFACE_NODE, "%s(config-if)# ", 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void rip_interface_sync(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
vrf = vrf_lookup_by_id(ifp->vrf_id);
|
||||||
|
if (vrf) {
|
||||||
|
struct rip_interface *ri;
|
||||||
|
|
||||||
|
ri = ifp->info;
|
||||||
|
if (ri)
|
||||||
|
ri->rip = vrf->info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Called when interface structure allocated. */
|
/* Called when interface structure allocated. */
|
||||||
static int rip_interface_new_hook(struct interface *ifp)
|
static int rip_interface_new_hook(struct interface *ifp)
|
||||||
{
|
{
|
||||||
ifp->info = rip_interface_new();
|
ifp->info = rip_interface_new();
|
||||||
|
rip_interface_sync(ifp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1220,13 +1265,6 @@ void rip_if_init(void)
|
|||||||
hook_register_prio(if_add, 0, rip_interface_new_hook);
|
hook_register_prio(if_add, 0, rip_interface_new_hook);
|
||||||
hook_register_prio(if_del, 0, rip_interface_delete_hook);
|
hook_register_prio(if_del, 0, rip_interface_delete_hook);
|
||||||
|
|
||||||
/* RIP network init. */
|
|
||||||
rip_enable_interface = vector_init(1);
|
|
||||||
rip_enable_network = route_table_init();
|
|
||||||
|
|
||||||
/* RIP passive interface. */
|
|
||||||
Vrip_passive_nondefault = vector_init(1);
|
|
||||||
|
|
||||||
/* Install interface node. */
|
/* Install interface node. */
|
||||||
install_node(&interface_node, rip_interface_config_write);
|
install_node(&interface_node, rip_interface_config_write);
|
||||||
if_cmd_init();
|
if_cmd_init();
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#ifndef _QUAGGA_RIP_INTERFACE_H
|
#ifndef _QUAGGA_RIP_INTERFACE_H
|
||||||
#define _QUAGGA_RIP_INTERFACE_H
|
#define _QUAGGA_RIP_INTERFACE_H
|
||||||
|
|
||||||
|
#include "zclient.h"
|
||||||
|
|
||||||
extern int rip_interface_down(int, struct zclient *, zebra_size_t, vrf_id_t);
|
extern int rip_interface_down(int, struct zclient *, zebra_size_t, vrf_id_t);
|
||||||
extern int rip_interface_up(int, struct zclient *, zebra_size_t, vrf_id_t);
|
extern int rip_interface_up(int, struct zclient *, zebra_size_t, vrf_id_t);
|
||||||
extern int rip_interface_add(int, struct zclient *, zebra_size_t, vrf_id_t);
|
extern int rip_interface_add(int, struct zclient *, zebra_size_t, vrf_id_t);
|
||||||
@ -28,5 +30,8 @@ extern int rip_interface_address_add(int, struct zclient *, zebra_size_t,
|
|||||||
vrf_id_t);
|
vrf_id_t);
|
||||||
extern int rip_interface_address_delete(int, struct zclient *, zebra_size_t,
|
extern int rip_interface_address_delete(int, struct zclient *, zebra_size_t,
|
||||||
vrf_id_t);
|
vrf_id_t);
|
||||||
|
extern int rip_interface_vrf_update(int command, struct zclient *zclient,
|
||||||
|
zebra_size_t length, vrf_id_t vrf_id);
|
||||||
|
extern void rip_interface_sync(struct interface *ifp);
|
||||||
|
|
||||||
#endif /* _QUAGGA_RIP_INTERFACE_H */
|
#endif /* _QUAGGA_RIP_INTERFACE_H */
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
#include "vrf.h"
|
#include "vrf.h"
|
||||||
|
#include "if_rmap.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
|
|
||||||
#include "ripd/ripd.h"
|
#include "ripd/ripd.h"
|
||||||
@ -46,7 +47,7 @@
|
|||||||
static struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};
|
static struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};
|
||||||
|
|
||||||
/* ripd privileges */
|
/* ripd privileges */
|
||||||
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND};
|
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
|
||||||
|
|
||||||
struct zebra_privs_t ripd_privs = {
|
struct zebra_privs_t ripd_privs = {
|
||||||
#if defined(FRR_USER)
|
#if defined(FRR_USER)
|
||||||
@ -59,7 +60,7 @@ struct zebra_privs_t ripd_privs = {
|
|||||||
.vty_group = VTY_GROUP,
|
.vty_group = VTY_GROUP,
|
||||||
#endif
|
#endif
|
||||||
.caps_p = _caps_p,
|
.caps_p = _caps_p,
|
||||||
.cap_num_p = 2,
|
.cap_num_p = array_size(_caps_p),
|
||||||
.cap_num_i = 0};
|
.cap_num_i = 0};
|
||||||
|
|
||||||
/* Master of threads. */
|
/* Master of threads. */
|
||||||
@ -81,8 +82,8 @@ static void sigint(void)
|
|||||||
{
|
{
|
||||||
zlog_notice("Terminating on signal");
|
zlog_notice("Terminating on signal");
|
||||||
|
|
||||||
rip_clean();
|
rip_vrf_terminate();
|
||||||
|
if_rmap_terminate();
|
||||||
rip_zclient_stop();
|
rip_zclient_stop();
|
||||||
frr_fini();
|
frr_fini();
|
||||||
|
|
||||||
@ -171,14 +172,13 @@ int main(int argc, char **argv)
|
|||||||
/* Library initialization. */
|
/* Library initialization. */
|
||||||
rip_error_init();
|
rip_error_init();
|
||||||
keychain_init();
|
keychain_init();
|
||||||
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
rip_vrf_init();
|
||||||
|
|
||||||
/* RIP related initialization. */
|
/* RIP related initialization. */
|
||||||
rip_init();
|
rip_init();
|
||||||
rip_if_init();
|
rip_if_init();
|
||||||
rip_cli_init();
|
rip_cli_init();
|
||||||
rip_zclient_init(master);
|
rip_zclient_init(master);
|
||||||
rip_peer_init();
|
|
||||||
|
|
||||||
frr_config_fork();
|
frr_config_fork();
|
||||||
frr_run(master);
|
frr_run(master);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
DEFINE_MGROUP(RIPD, "ripd")
|
DEFINE_MGROUP(RIPD, "ripd")
|
||||||
DEFINE_MTYPE(RIPD, RIP, "RIP structure")
|
DEFINE_MTYPE(RIPD, RIP, "RIP structure")
|
||||||
|
DEFINE_MTYPE(RIPD, RIP_VRF_NAME, "RIP VRF name")
|
||||||
DEFINE_MTYPE(RIPD, RIP_INFO, "RIP route info")
|
DEFINE_MTYPE(RIPD, RIP_INFO, "RIP route info")
|
||||||
DEFINE_MTYPE(RIPD, RIP_INTERFACE, "RIP interface")
|
DEFINE_MTYPE(RIPD, RIP_INTERFACE, "RIP interface")
|
||||||
DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String")
|
DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String")
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
DECLARE_MGROUP(RIPD)
|
DECLARE_MGROUP(RIPD)
|
||||||
DECLARE_MTYPE(RIP)
|
DECLARE_MTYPE(RIP)
|
||||||
|
DECLARE_MTYPE(RIP_VRF_NAME)
|
||||||
DECLARE_MTYPE(RIP_INFO)
|
DECLARE_MTYPE(RIP_INFO)
|
||||||
DECLARE_MTYPE(RIP_INTERFACE)
|
DECLARE_MTYPE(RIP_INTERFACE)
|
||||||
DECLARE_MTYPE(RIP_INTERFACE_STRING)
|
DECLARE_MTYPE(RIP_INTERFACE_STRING)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -29,28 +29,27 @@
|
|||||||
|
|
||||||
#include "ripd/ripd.h"
|
#include "ripd/ripd.h"
|
||||||
|
|
||||||
static struct list *rip_offset_list_master;
|
|
||||||
|
|
||||||
#define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIP_OFFSET_LIST_IN].alist_name)
|
#define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIP_OFFSET_LIST_IN].alist_name)
|
||||||
#define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_IN].metric)
|
#define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_IN].metric)
|
||||||
|
|
||||||
#define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIP_OFFSET_LIST_OUT].alist_name)
|
#define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIP_OFFSET_LIST_OUT].alist_name)
|
||||||
#define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_OUT].metric)
|
#define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_OUT].metric)
|
||||||
|
|
||||||
struct rip_offset_list *rip_offset_list_new(const char *ifname)
|
struct rip_offset_list *rip_offset_list_new(struct rip *rip, const char *ifname)
|
||||||
{
|
{
|
||||||
struct rip_offset_list *offset;
|
struct rip_offset_list *offset;
|
||||||
|
|
||||||
offset = XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list));
|
offset = XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list));
|
||||||
|
offset->rip = rip;
|
||||||
offset->ifname = strdup(ifname);
|
offset->ifname = strdup(ifname);
|
||||||
listnode_add_sort(rip_offset_list_master, offset);
|
listnode_add_sort(rip->offset_list_master, offset);
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void offset_list_del(struct rip_offset_list *offset)
|
void offset_list_del(struct rip_offset_list *offset)
|
||||||
{
|
{
|
||||||
listnode_delete(rip_offset_list_master, offset);
|
listnode_delete(offset->rip->offset_list_master, offset);
|
||||||
if (OFFSET_LIST_IN_NAME(offset))
|
if (OFFSET_LIST_IN_NAME(offset))
|
||||||
free(OFFSET_LIST_IN_NAME(offset));
|
free(OFFSET_LIST_IN_NAME(offset));
|
||||||
if (OFFSET_LIST_OUT_NAME(offset))
|
if (OFFSET_LIST_OUT_NAME(offset))
|
||||||
@ -59,12 +58,13 @@ void offset_list_del(struct rip_offset_list *offset)
|
|||||||
XFREE(MTYPE_RIP_OFFSET_LIST, offset);
|
XFREE(MTYPE_RIP_OFFSET_LIST, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rip_offset_list *rip_offset_list_lookup(const char *ifname)
|
struct rip_offset_list *rip_offset_list_lookup(struct rip *rip,
|
||||||
|
const char *ifname)
|
||||||
{
|
{
|
||||||
struct rip_offset_list *offset;
|
struct rip_offset_list *offset;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(rip_offset_list_master, node, nnode, offset)) {
|
for (ALL_LIST_ELEMENTS(rip->offset_list_master, node, nnode, offset)) {
|
||||||
if (strcmp(offset->ifname, ifname) == 0)
|
if (strcmp(offset->ifname, ifname) == 0)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -75,11 +75,12 @@ struct rip_offset_list *rip_offset_list_lookup(const char *ifname)
|
|||||||
int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp,
|
int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp,
|
||||||
uint32_t *metric)
|
uint32_t *metric)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = ifp->info;
|
||||||
struct rip_offset_list *offset;
|
struct rip_offset_list *offset;
|
||||||
struct access_list *alist;
|
struct access_list *alist;
|
||||||
|
|
||||||
/* Look up offset-list with interface name. */
|
/* Look up offset-list with interface name. */
|
||||||
offset = rip_offset_list_lookup(ifp->name);
|
offset = rip_offset_list_lookup(ri->rip, ifp->name);
|
||||||
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset));
|
alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset));
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Look up offset-list without interface name. */
|
/* Look up offset-list without interface name. */
|
||||||
offset = rip_offset_list_lookup("*");
|
offset = rip_offset_list_lookup(ri->rip, "*");
|
||||||
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset));
|
alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset));
|
||||||
|
|
||||||
@ -111,11 +112,12 @@ int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp,
|
|||||||
int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp,
|
int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp,
|
||||||
uint32_t *metric)
|
uint32_t *metric)
|
||||||
{
|
{
|
||||||
|
struct rip_interface *ri = ifp->info;
|
||||||
struct rip_offset_list *offset;
|
struct rip_offset_list *offset;
|
||||||
struct access_list *alist;
|
struct access_list *alist;
|
||||||
|
|
||||||
/* Look up offset-list with interface name. */
|
/* Look up offset-list with interface name. */
|
||||||
offset = rip_offset_list_lookup(ifp->name);
|
offset = rip_offset_list_lookup(ri->rip, ifp->name);
|
||||||
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP,
|
alist = access_list_lookup(AFI_IP,
|
||||||
OFFSET_LIST_OUT_NAME(offset));
|
OFFSET_LIST_OUT_NAME(offset));
|
||||||
@ -130,7 +132,7 @@ int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Look up offset-list without interface name. */
|
/* Look up offset-list without interface name. */
|
||||||
offset = rip_offset_list_lookup("*");
|
offset = rip_offset_list_lookup(ri->rip, "*");
|
||||||
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP,
|
alist = access_list_lookup(AFI_IP,
|
||||||
OFFSET_LIST_OUT_NAME(offset));
|
OFFSET_LIST_OUT_NAME(offset));
|
||||||
@ -146,24 +148,7 @@ int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int offset_list_cmp(struct rip_offset_list *o1,
|
int offset_list_cmp(struct rip_offset_list *o1, struct rip_offset_list *o2)
|
||||||
struct rip_offset_list *o2)
|
|
||||||
{
|
{
|
||||||
return strcmp(o1->ifname, o2->ifname);
|
return strcmp(o1->ifname, o2->ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_offset_init(void)
|
|
||||||
{
|
|
||||||
rip_offset_list_master = list_new();
|
|
||||||
rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
|
|
||||||
rip_offset_list_master->del = (void (*)(void *))offset_list_del;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rip_offset_clean(void)
|
|
||||||
{
|
|
||||||
list_delete(&rip_offset_list_master);
|
|
||||||
|
|
||||||
rip_offset_list_master = list_new();
|
|
||||||
rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
|
|
||||||
rip_offset_list_master->del = (void (*)(void *))offset_list_del;
|
|
||||||
}
|
|
||||||
|
@ -29,9 +29,6 @@
|
|||||||
|
|
||||||
#include "ripd/ripd.h"
|
#include "ripd/ripd.h"
|
||||||
|
|
||||||
/* Linked list of RIP peer. */
|
|
||||||
struct list *peer_list;
|
|
||||||
|
|
||||||
static struct rip_peer *rip_peer_new(void)
|
static struct rip_peer *rip_peer_new(void)
|
||||||
{
|
{
|
||||||
return XCALLOC(MTYPE_RIP_PEER, sizeof(struct rip_peer));
|
return XCALLOC(MTYPE_RIP_PEER, sizeof(struct rip_peer));
|
||||||
@ -39,27 +36,28 @@ static struct rip_peer *rip_peer_new(void)
|
|||||||
|
|
||||||
static void rip_peer_free(struct rip_peer *peer)
|
static void rip_peer_free(struct rip_peer *peer)
|
||||||
{
|
{
|
||||||
|
RIP_TIMER_OFF(peer->t_timeout);
|
||||||
XFREE(MTYPE_RIP_PEER, peer);
|
XFREE(MTYPE_RIP_PEER, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rip_peer *rip_peer_lookup(struct in_addr *addr)
|
struct rip_peer *rip_peer_lookup(struct rip *rip, struct in_addr *addr)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
|
||||||
if (IPV4_ADDR_SAME(&peer->addr, addr))
|
if (IPV4_ADDR_SAME(&peer->addr, addr))
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rip_peer *rip_peer_lookup_next(struct in_addr *addr)
|
struct rip_peer *rip_peer_lookup_next(struct rip *rip, struct in_addr *addr)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
|
||||||
if (htonl(peer->addr.s_addr) > htonl(addr->s_addr))
|
if (htonl(peer->addr.s_addr) > htonl(addr->s_addr))
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
@ -72,26 +70,27 @@ static int rip_peer_timeout(struct thread *t)
|
|||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
|
|
||||||
peer = THREAD_ARG(t);
|
peer = THREAD_ARG(t);
|
||||||
listnode_delete(peer_list, peer);
|
listnode_delete(peer->rip->peer_list, peer);
|
||||||
rip_peer_free(peer);
|
rip_peer_free(peer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get RIP peer. At the same time update timeout thread. */
|
/* Get RIP peer. At the same time update timeout thread. */
|
||||||
static struct rip_peer *rip_peer_get(struct in_addr *addr)
|
static struct rip_peer *rip_peer_get(struct rip *rip, struct in_addr *addr)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
|
|
||||||
peer = rip_peer_lookup(addr);
|
peer = rip_peer_lookup(rip, addr);
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if (peer->t_timeout)
|
if (peer->t_timeout)
|
||||||
thread_cancel(peer->t_timeout);
|
thread_cancel(peer->t_timeout);
|
||||||
} else {
|
} else {
|
||||||
peer = rip_peer_new();
|
peer = rip_peer_new();
|
||||||
|
peer->rip = rip;
|
||||||
peer->addr = *addr;
|
peer->addr = *addr;
|
||||||
listnode_add_sort(peer_list, peer);
|
listnode_add_sort(rip->peer_list, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update timeout thread. */
|
/* Update timeout thread. */
|
||||||
@ -105,24 +104,24 @@ static struct rip_peer *rip_peer_get(struct in_addr *addr)
|
|||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_peer_update(struct sockaddr_in *from, uint8_t version)
|
void rip_peer_update(struct rip *rip, struct sockaddr_in *from, uint8_t version)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
peer = rip_peer_get(&from->sin_addr);
|
peer = rip_peer_get(rip, &from->sin_addr);
|
||||||
peer->version = version;
|
peer->version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_peer_bad_route(struct sockaddr_in *from)
|
void rip_peer_bad_route(struct rip *rip, struct sockaddr_in *from)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
peer = rip_peer_get(&from->sin_addr);
|
peer = rip_peer_get(rip, &from->sin_addr);
|
||||||
peer->recv_badroutes++;
|
peer->recv_badroutes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_peer_bad_packet(struct sockaddr_in *from)
|
void rip_peer_bad_packet(struct rip *rip, struct sockaddr_in *from)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
peer = rip_peer_get(&from->sin_addr);
|
peer = rip_peer_get(rip, &from->sin_addr);
|
||||||
peer->recv_badpackets++;
|
peer->recv_badpackets++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,14 +154,14 @@ static char *rip_peer_uptime(struct rip_peer *peer, char *buf, size_t len)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_peer_display(struct vty *vty)
|
void rip_peer_display(struct vty *vty, struct rip *rip)
|
||||||
{
|
{
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
#define RIP_UPTIME_LEN 25
|
#define RIP_UPTIME_LEN 25
|
||||||
char timebuf[RIP_UPTIME_LEN];
|
char timebuf[RIP_UPTIME_LEN];
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
|
||||||
vty_out(vty, " %-16s %9d %9d %9d %s\n",
|
vty_out(vty, " %-16s %9d %9d %9d %s\n",
|
||||||
inet_ntoa(peer->addr), peer->recv_badpackets,
|
inet_ntoa(peer->addr), peer->recv_badpackets,
|
||||||
peer->recv_badroutes, ZEBRA_RIP_DISTANCE_DEFAULT,
|
peer->recv_badroutes, ZEBRA_RIP_DISTANCE_DEFAULT,
|
||||||
@ -170,7 +169,7 @@ void rip_peer_display(struct vty *vty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2)
|
int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2)
|
||||||
{
|
{
|
||||||
if (p2->addr.s_addr == p1->addr.s_addr)
|
if (p2->addr.s_addr == p1->addr.s_addr)
|
||||||
return 0;
|
return 0;
|
||||||
@ -178,8 +177,7 @@ static int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2)
|
|||||||
return (htonl(p1->addr.s_addr) < htonl(p2->addr.s_addr)) ? -1 : 1;
|
return (htonl(p1->addr.s_addr) < htonl(p2->addr.s_addr)) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_peer_init(void)
|
void rip_peer_list_del(void *arg)
|
||||||
{
|
{
|
||||||
peer_list = list_new();
|
rip_peer_free(arg);
|
||||||
peer_list->cmp = (int (*)(void *, void *))rip_peer_list_cmp;
|
|
||||||
}
|
}
|
||||||
|
@ -156,17 +156,23 @@ static uint8_t *rip2Globals(struct variable *v, oid name[], size_t *length,
|
|||||||
int exact, size_t *var_len,
|
int exact, size_t *var_len,
|
||||||
WriteMethod **write_method)
|
WriteMethod **write_method)
|
||||||
{
|
{
|
||||||
|
struct rip *rip;
|
||||||
|
|
||||||
if (smux_header_generic(v, name, length, exact, var_len, write_method)
|
if (smux_header_generic(v, name, length, exact, var_len, write_method)
|
||||||
== MATCH_FAILED)
|
== MATCH_FAILED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
|
||||||
|
if (!rip)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Retrun global counter. */
|
/* Retrun global counter. */
|
||||||
switch (v->magic) {
|
switch (v->magic) {
|
||||||
case RIP2GLOBALROUTECHANGES:
|
case RIP2GLOBALROUTECHANGES:
|
||||||
return SNMP_INTEGER(rip_global_route_changes);
|
return SNMP_INTEGER(rip->counters.route_changes);
|
||||||
break;
|
break;
|
||||||
case RIP2GLOBALQUERIES:
|
case RIP2GLOBALQUERIES:
|
||||||
return SNMP_INTEGER(rip_global_queries);
|
return SNMP_INTEGER(rip->counters.queries);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -281,9 +287,14 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[],
|
|||||||
size_t *length, struct in_addr *addr,
|
size_t *length, struct in_addr *addr,
|
||||||
int exact)
|
int exact)
|
||||||
{
|
{
|
||||||
|
struct rip *rip;
|
||||||
int len;
|
int len;
|
||||||
struct rip_peer *peer;
|
struct rip_peer *peer;
|
||||||
|
|
||||||
|
rip = rip_lookup_by_vrf_id(VRF_DEFAULT);
|
||||||
|
if (!rip)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (exact) {
|
if (exact) {
|
||||||
/* Check the length. */
|
/* Check the length. */
|
||||||
if (*length - v->namelen != sizeof(struct in_addr) + 1)
|
if (*length - v->namelen != sizeof(struct in_addr) + 1)
|
||||||
@ -291,7 +302,7 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[],
|
|||||||
|
|
||||||
oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr);
|
oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr);
|
||||||
|
|
||||||
peer = rip_peer_lookup(addr);
|
peer = rip_peer_lookup(rip, addr);
|
||||||
|
|
||||||
if (peer->domain
|
if (peer->domain
|
||||||
== (int)name[v->namelen + sizeof(struct in_addr)])
|
== (int)name[v->namelen + sizeof(struct in_addr)])
|
||||||
@ -306,7 +317,7 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[],
|
|||||||
oid2in_addr(name + v->namelen, len, addr);
|
oid2in_addr(name + v->namelen, len, addr);
|
||||||
|
|
||||||
len = *length - v->namelen;
|
len = *length - v->namelen;
|
||||||
peer = rip_peer_lookup(addr);
|
peer = rip_peer_lookup(rip, addr);
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if ((len < (int)sizeof(struct in_addr) + 1)
|
if ((len < (int)sizeof(struct in_addr) + 1)
|
||||||
|| (peer->domain
|
|| (peer->domain
|
||||||
@ -321,7 +332,7 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[],
|
|||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peer = rip_peer_lookup_next(addr);
|
peer = rip_peer_lookup_next(rip, addr);
|
||||||
|
|
||||||
if (!peer)
|
if (!peer)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -402,10 +413,10 @@ static long rip2IfConfSend(struct rip_interface *ri)
|
|||||||
return ripVersion2;
|
return ripVersion2;
|
||||||
else if (ri->ri_send & RIPv1)
|
else if (ri->ri_send & RIPv1)
|
||||||
return ripVersion1;
|
return ripVersion1;
|
||||||
else if (rip) {
|
else if (ri->rip) {
|
||||||
if (rip->version_send == RIPv2)
|
if (ri->rip->version_send == RIPv2)
|
||||||
return ripVersion2;
|
return ripVersion2;
|
||||||
else if (rip->version_send == RIPv1)
|
else if (ri->rip->version_send == RIPv1)
|
||||||
return ripVersion1;
|
return ripVersion1;
|
||||||
}
|
}
|
||||||
return doNotSend;
|
return doNotSend;
|
||||||
@ -423,7 +434,7 @@ static long rip2IfConfReceive(struct rip_interface *ri)
|
|||||||
if (!ri->running)
|
if (!ri->running)
|
||||||
return doNotReceive;
|
return doNotReceive;
|
||||||
|
|
||||||
recvv = (ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv
|
recvv = (ri->ri_receive == RI_RIP_UNSPEC) ? ri->rip->version_recv
|
||||||
: ri->ri_receive;
|
: ri->ri_receive;
|
||||||
if (recvv == RI_RIP_VERSION_1_AND_2)
|
if (recvv == RI_RIP_VERSION_1_AND_2)
|
||||||
return rip1OrRip2;
|
return rip1OrRip2;
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
struct zclient *zclient = NULL;
|
struct zclient *zclient = NULL;
|
||||||
|
|
||||||
/* Send ECMP routes to zebra. */
|
/* Send ECMP routes to zebra. */
|
||||||
static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd)
|
static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp,
|
||||||
|
uint8_t cmd)
|
||||||
{
|
{
|
||||||
struct list *list = (struct list *)rp->info;
|
struct list *list = (struct list *)rp->info;
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
@ -46,7 +47,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = VRF_DEFAULT;
|
api.vrf_id = rip->vrf->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_RIP;
|
api.type = ZEBRA_ROUTE_RIP;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd)
|
|||||||
if (count >= MULTIPATH_NUM)
|
if (count >= MULTIPATH_NUM)
|
||||||
break;
|
break;
|
||||||
api_nh = &api.nexthops[count];
|
api_nh = &api.nexthops[count];
|
||||||
api_nh->vrf_id = VRF_DEFAULT;
|
api_nh->vrf_id = rip->vrf->vrf_id;
|
||||||
api_nh->gate = rinfo->nh.gate;
|
api_nh->gate = rinfo->nh.gate;
|
||||||
api_nh->type = NEXTHOP_TYPE_IPV4;
|
api_nh->type = NEXTHOP_TYPE_IPV4;
|
||||||
if (cmd == ZEBRA_ROUTE_ADD)
|
if (cmd == ZEBRA_ROUTE_ADD)
|
||||||
@ -101,28 +102,30 @@ static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd)
|
|||||||
inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen);
|
inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
rip_global_route_changes++;
|
rip->counters.route_changes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add/update ECMP routes to zebra. */
|
/* Add/update ECMP routes to zebra. */
|
||||||
void rip_zebra_ipv4_add(struct route_node *rp)
|
void rip_zebra_ipv4_add(struct rip *rip, struct route_node *rp)
|
||||||
{
|
{
|
||||||
rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_ADD);
|
rip_zebra_ipv4_send(rip, rp, ZEBRA_ROUTE_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete ECMP routes from zebra. */
|
/* Delete ECMP routes from zebra. */
|
||||||
void rip_zebra_ipv4_delete(struct route_node *rp)
|
void rip_zebra_ipv4_delete(struct rip *rip, struct route_node *rp)
|
||||||
{
|
{
|
||||||
rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_DELETE);
|
rip_zebra_ipv4_send(rip, rp, ZEBRA_ROUTE_DELETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zebra route add and delete treatment. */
|
/* Zebra route add and delete treatment. */
|
||||||
static int rip_zebra_read_route(int command, struct zclient *zclient,
|
static int rip_zebra_read_route(int command, struct zclient *zclient,
|
||||||
zebra_size_t length, vrf_id_t vrf_id)
|
zebra_size_t length, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
|
struct rip *rip;
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
struct nexthop nh;
|
struct nexthop nh;
|
||||||
|
|
||||||
|
rip = rip_lookup_by_vrf_id(vrf_id);
|
||||||
if (!rip)
|
if (!rip)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -136,68 +139,95 @@ static int rip_zebra_read_route(int command, struct zclient *zclient,
|
|||||||
|
|
||||||
/* Then fetch IPv4 prefixes. */
|
/* Then fetch IPv4 prefixes. */
|
||||||
if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
||||||
rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE,
|
rip_redistribute_add(rip, api.type, RIP_ROUTE_REDISTRIBUTE,
|
||||||
(struct prefix_ipv4 *)&api.prefix, &nh,
|
(struct prefix_ipv4 *)&api.prefix, &nh,
|
||||||
api.metric, api.distance, api.tag);
|
api.metric, api.distance, api.tag);
|
||||||
else if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL)
|
else if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL)
|
||||||
rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE,
|
rip_redistribute_delete(rip, api.type, RIP_ROUTE_REDISTRIBUTE,
|
||||||
(struct prefix_ipv4 *)&api.prefix,
|
(struct prefix_ipv4 *)&api.prefix,
|
||||||
nh.ifindex);
|
nh.ifindex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_redistribute_conf_update(int type)
|
void rip_redistribute_conf_update(struct rip *rip, int type)
|
||||||
{
|
{
|
||||||
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
|
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
|
||||||
0, VRF_DEFAULT);
|
0, rip->vrf->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_redistribute_conf_delete(int type)
|
void rip_redistribute_conf_delete(struct rip *rip, int type)
|
||||||
{
|
{
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
|
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
|
||||||
AFI_IP, type, 0, VRF_DEFAULT);
|
AFI_IP, type, 0, rip->vrf->vrf_id);
|
||||||
|
|
||||||
/* Remove the routes from RIP table. */
|
/* Remove the routes from RIP table. */
|
||||||
rip_redistribute_withdraw(type);
|
rip_redistribute_withdraw(rip, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rip_redistribute_check(int type)
|
int rip_redistribute_check(struct rip *rip, int type)
|
||||||
{
|
{
|
||||||
return vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT);
|
return rip->redist[type].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_redistribute_clean(void)
|
void rip_redistribute_enable(struct rip *rip)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
if (!vrf_bitmap_check(zclient->redist[AFI_IP][i], VRF_DEFAULT))
|
if (!rip_redistribute_check(rip, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (zclient->sock > 0)
|
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
|
||||||
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE,
|
i, 0, rip->vrf->vrf_id);
|
||||||
zclient, AFI_IP, i, 0,
|
|
||||||
VRF_DEFAULT);
|
|
||||||
|
|
||||||
vrf_bitmap_unset(zclient->redist[AFI_IP][i], VRF_DEFAULT);
|
|
||||||
|
|
||||||
/* Remove the routes from RIP table. */
|
|
||||||
rip_redistribute_withdraw(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rip_show_redistribute_config(struct vty *vty)
|
void rip_redistribute_disable(struct rip *rip)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
|
if (!rip_redistribute_check(rip, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
|
||||||
|
AFI_IP, i, 0, rip->vrf->vrf_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rip_show_redistribute_config(struct vty *vty, struct rip *rip)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
if (i == zclient->redist_default
|
if (i == zclient->redist_default
|
||||||
|| !vrf_bitmap_check(zclient->redist[AFI_IP][i],
|
|| !rip_redistribute_check(rip, i))
|
||||||
VRF_DEFAULT))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vty_out(vty, " %s", zebra_route_string(i));
|
vty_out(vty, " %s", zebra_route_string(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rip_zebra_vrf_register(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
if (vrf->vrf_id == VRF_DEFAULT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IS_RIP_DEBUG_EVENT)
|
||||||
|
zlog_debug("%s: register VRF %s(%u) to zebra", __func__,
|
||||||
|
vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
|
zclient_send_reg_requests(zclient, vrf->vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rip_zebra_vrf_deregister(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
if (vrf->vrf_id == VRF_DEFAULT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IS_RIP_DEBUG_EVENT)
|
||||||
|
zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__,
|
||||||
|
vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
|
zclient_send_dereg_requests(zclient, vrf->vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
static void rip_zebra_connected(struct zclient *zclient)
|
static void rip_zebra_connected(struct zclient *zclient)
|
||||||
{
|
{
|
||||||
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
||||||
@ -215,6 +245,7 @@ void rip_zclient_init(struct thread_master *master)
|
|||||||
zclient->interface_address_delete = rip_interface_address_delete;
|
zclient->interface_address_delete = rip_interface_address_delete;
|
||||||
zclient->interface_up = rip_interface_up;
|
zclient->interface_up = rip_interface_up;
|
||||||
zclient->interface_down = rip_interface_down;
|
zclient->interface_down = rip_interface_down;
|
||||||
|
zclient->interface_vrf_update = rip_interface_vrf_update;
|
||||||
zclient->redistribute_route_add = rip_zebra_read_route;
|
zclient->redistribute_route_add = rip_zebra_read_route;
|
||||||
zclient->redistribute_route_del = rip_zebra_read_route;
|
zclient->redistribute_route_del = rip_zebra_read_route;
|
||||||
}
|
}
|
||||||
|
898
ripd/ripd.c
898
ripd/ripd.c
File diff suppressed because it is too large
Load Diff
190
ripd/ripd.h
190
ripd/ripd.h
@ -99,6 +99,17 @@
|
|||||||
|
|
||||||
/* RIP structure. */
|
/* RIP structure. */
|
||||||
struct rip {
|
struct rip {
|
||||||
|
RB_ENTRY(rip) entry;
|
||||||
|
|
||||||
|
/* VRF this routing instance is associated with. */
|
||||||
|
char *vrf_name;
|
||||||
|
|
||||||
|
/* VRF backpointer (might be NULL if the VRF doesn't exist). */
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
/* Status of the routing instance. */
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
/* RIP socket. */
|
/* RIP socket. */
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
@ -112,9 +123,12 @@ struct rip {
|
|||||||
/* RIP routing information base. */
|
/* RIP routing information base. */
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
|
|
||||||
/* RIP neighbor. */
|
/* RIP static neighbors. */
|
||||||
struct route_table *neighbor;
|
struct route_table *neighbor;
|
||||||
|
|
||||||
|
/* Linked list of RIP peers. */
|
||||||
|
struct list *peer_list;
|
||||||
|
|
||||||
/* RIP threads. */
|
/* RIP threads. */
|
||||||
struct thread *t_read;
|
struct thread *t_read;
|
||||||
|
|
||||||
@ -144,20 +158,46 @@ struct rip {
|
|||||||
/* Are we in passive-interface default mode? */
|
/* Are we in passive-interface default mode? */
|
||||||
bool passive_default;
|
bool passive_default;
|
||||||
|
|
||||||
/* For redistribute route map. */
|
/* RIP enabled interfaces. */
|
||||||
|
vector enable_interface;
|
||||||
|
|
||||||
|
/* RIP enabled networks. */
|
||||||
|
struct route_table *enable_network;
|
||||||
|
|
||||||
|
/* Vector to store passive-interface name. */
|
||||||
|
vector passive_nondefault;
|
||||||
|
|
||||||
|
/* RIP offset-lists. */
|
||||||
|
struct list *offset_list_master;
|
||||||
|
|
||||||
|
/* RIP redistribute configuration. */
|
||||||
struct {
|
struct {
|
||||||
char *name;
|
bool enabled;
|
||||||
struct route_map *map;
|
struct {
|
||||||
|
char *name;
|
||||||
|
struct route_map *map;
|
||||||
|
} route_map;
|
||||||
bool metric_config;
|
bool metric_config;
|
||||||
uint8_t metric;
|
uint8_t metric;
|
||||||
} route_map[ZEBRA_ROUTE_MAX];
|
} redist[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
/* For distribute-list container */
|
/* For distribute-list container */
|
||||||
struct distribute_ctx *distribute_ctx;
|
struct distribute_ctx *distribute_ctx;
|
||||||
|
|
||||||
/* For if_rmap container */
|
/* For if_rmap container */
|
||||||
struct if_rmap_ctx *if_rmap_ctx;
|
struct if_rmap_ctx *if_rmap_ctx;
|
||||||
|
|
||||||
|
/* Counters for SNMP. */
|
||||||
|
struct {
|
||||||
|
/* RIP route changes. */
|
||||||
|
long route_changes;
|
||||||
|
|
||||||
|
/* RIP queries. */
|
||||||
|
long queries;
|
||||||
|
} counters;
|
||||||
};
|
};
|
||||||
|
RB_HEAD(rip_instance_head, rip);
|
||||||
|
RB_PROTOTYPE(rip_instance_head, rip, entry, rip_instance_compare)
|
||||||
|
|
||||||
/* RIP routing table entry which belong to rip_packet. */
|
/* RIP routing table entry which belong to rip_packet. */
|
||||||
struct rte {
|
struct rte {
|
||||||
@ -225,11 +265,6 @@ struct rip_info {
|
|||||||
struct route_node *rp;
|
struct route_node *rp;
|
||||||
|
|
||||||
uint8_t distance;
|
uint8_t distance;
|
||||||
|
|
||||||
#ifdef NEW_RIP_TABLE
|
|
||||||
struct rip_info *next;
|
|
||||||
struct rip_info *prev;
|
|
||||||
#endif /* NEW_RIP_TABLE */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -240,6 +275,9 @@ typedef enum {
|
|||||||
|
|
||||||
/* RIP specific interface configuration. */
|
/* RIP specific interface configuration. */
|
||||||
struct rip_interface {
|
struct rip_interface {
|
||||||
|
/* Parent routing instance. */
|
||||||
|
struct rip *rip;
|
||||||
|
|
||||||
/* RIP is enabled on this interface. */
|
/* RIP is enabled on this interface. */
|
||||||
int enable_network;
|
int enable_network;
|
||||||
int enable_interface;
|
int enable_interface;
|
||||||
@ -297,6 +335,9 @@ struct rip_interface {
|
|||||||
|
|
||||||
/* RIP peer information. */
|
/* RIP peer information. */
|
||||||
struct rip_peer {
|
struct rip_peer {
|
||||||
|
/* Parent routing instance. */
|
||||||
|
struct rip *rip;
|
||||||
|
|
||||||
/* Peer address. */
|
/* Peer address. */
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|
||||||
@ -369,6 +410,9 @@ enum rip_event {
|
|||||||
#define RIP_OFFSET_LIST_MAX 2
|
#define RIP_OFFSET_LIST_MAX 2
|
||||||
|
|
||||||
struct rip_offset_list {
|
struct rip_offset_list {
|
||||||
|
/* Parent routing instance. */
|
||||||
|
struct rip *rip;
|
||||||
|
|
||||||
char *ifname;
|
char *ifname;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -380,104 +424,114 @@ struct rip_offset_list {
|
|||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
extern void rip_init(void);
|
extern void rip_init(void);
|
||||||
extern void rip_clean(void);
|
extern void rip_clean(struct rip *rip);
|
||||||
extern void rip_clean_network(void);
|
extern void rip_clean_network(struct rip *rip);
|
||||||
extern void rip_interfaces_clean(void);
|
extern void rip_interfaces_clean(struct rip *rip);
|
||||||
extern int rip_passive_nondefault_set(const char *ifname);
|
extern int rip_passive_nondefault_set(struct rip *rip, const char *ifname);
|
||||||
extern int rip_passive_nondefault_unset(const char *ifname);
|
extern int rip_passive_nondefault_unset(struct rip *rip, const char *ifname);
|
||||||
extern void rip_passive_nondefault_clean(void);
|
extern void rip_passive_nondefault_clean(struct rip *rip);
|
||||||
extern void rip_if_init(void);
|
extern void rip_if_init(void);
|
||||||
extern void rip_if_down_all(void);
|
|
||||||
extern void rip_route_map_init(void);
|
extern void rip_route_map_init(void);
|
||||||
|
extern void rip_zebra_vrf_register(struct vrf *vrf);
|
||||||
|
extern void rip_zebra_vrf_deregister(struct vrf *vrf);
|
||||||
extern void rip_zclient_init(struct thread_master *);
|
extern void rip_zclient_init(struct thread_master *);
|
||||||
extern void rip_zclient_stop(void);
|
extern void rip_zclient_stop(void);
|
||||||
extern int if_check_address(struct in_addr addr);
|
extern int if_check_address(struct rip *rip, struct in_addr addr);
|
||||||
extern int rip_create(int socket);
|
extern struct rip *rip_lookup_by_vrf_id(vrf_id_t vrf_id);
|
||||||
|
extern struct rip *rip_lookup_by_vrf_name(const char *vrf_name);
|
||||||
|
extern struct rip *rip_create(const char *vrf_name, struct vrf *vrf,
|
||||||
|
int socket);
|
||||||
|
|
||||||
extern int rip_request_send(struct sockaddr_in *, struct interface *, uint8_t,
|
extern int rip_request_send(struct sockaddr_in *, struct interface *, uint8_t,
|
||||||
struct connected *);
|
struct connected *);
|
||||||
extern int rip_neighbor_lookup(struct sockaddr_in *);
|
extern int rip_neighbor_lookup(struct rip *rip, struct sockaddr_in *from);
|
||||||
extern int rip_neighbor_add(struct prefix_ipv4 *p);
|
extern int rip_neighbor_add(struct rip *rip, struct prefix_ipv4 *p);
|
||||||
extern int rip_neighbor_delete(struct prefix_ipv4 *p);
|
extern int rip_neighbor_delete(struct rip *rip, struct prefix_ipv4 *p);
|
||||||
|
|
||||||
extern int rip_enable_network_add(struct prefix *p);
|
extern int rip_enable_network_add(struct rip *rip, struct prefix *p);
|
||||||
extern int rip_enable_network_delete(struct prefix *p);
|
extern int rip_enable_network_delete(struct rip *rip, struct prefix *p);
|
||||||
extern int rip_enable_if_add(const char *ifname);
|
extern int rip_enable_if_add(struct rip *rip, const char *ifname);
|
||||||
extern int rip_enable_if_delete(const char *ifname);
|
extern int rip_enable_if_delete(struct rip *rip, const char *ifname);
|
||||||
|
|
||||||
extern void rip_event(enum rip_event, int);
|
extern void rip_event(struct rip *rip, enum rip_event event, int sock);
|
||||||
extern void rip_ecmp_disable(void);
|
extern void rip_ecmp_disable(struct rip *rip);
|
||||||
|
|
||||||
extern int rip_create_socket(void);
|
extern int rip_create_socket(struct vrf *vrf);
|
||||||
|
|
||||||
extern int rip_redistribute_check(int);
|
extern int rip_redistribute_check(struct rip *rip, int type);
|
||||||
extern void rip_redistribute_conf_update(int type);
|
extern void rip_redistribute_conf_update(struct rip *rip, int type);
|
||||||
extern void rip_redistribute_conf_delete(int type);
|
extern void rip_redistribute_conf_delete(struct rip *rip, int type);
|
||||||
extern void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
|
extern void rip_redistribute_add(struct rip *rip, int type, int sub_type,
|
||||||
struct nexthop *nh, unsigned int metric,
|
struct prefix_ipv4 *p, struct nexthop *nh,
|
||||||
unsigned char distance, route_tag_t tag);
|
unsigned int metric, unsigned char distance,
|
||||||
extern void rip_redistribute_delete(int, int, struct prefix_ipv4 *, ifindex_t);
|
route_tag_t tag);
|
||||||
extern void rip_redistribute_withdraw(int);
|
extern void rip_redistribute_delete(struct rip *rip, int type, int sub_type,
|
||||||
extern void rip_zebra_ipv4_add(struct route_node *);
|
struct prefix_ipv4 *p, ifindex_t ifindex);
|
||||||
extern void rip_zebra_ipv4_delete(struct route_node *);
|
extern void rip_redistribute_withdraw(struct rip *rip, int type);
|
||||||
|
extern void rip_zebra_ipv4_add(struct rip *rip, struct route_node *rp);
|
||||||
|
extern void rip_zebra_ipv4_delete(struct rip *rip, struct route_node *rp);
|
||||||
extern void rip_interface_multicast_set(int, struct connected *);
|
extern void rip_interface_multicast_set(int, struct connected *);
|
||||||
extern void rip_distribute_update_interface(struct interface *);
|
extern void rip_distribute_update_interface(struct interface *);
|
||||||
extern void rip_if_rmap_update_interface(struct interface *ifp);
|
extern void rip_if_rmap_update_interface(struct interface *ifp);
|
||||||
extern int rip_show_network_config(struct vty *);
|
|
||||||
extern void rip_show_redistribute_config(struct vty *);
|
|
||||||
|
|
||||||
extern void rip_peer_init(void);
|
extern int rip_show_network_config(struct vty *vty, struct rip *rip);
|
||||||
extern void rip_peer_update(struct sockaddr_in *, uint8_t);
|
extern void rip_show_redistribute_config(struct vty *vty, struct rip *rip);
|
||||||
extern void rip_peer_bad_route(struct sockaddr_in *);
|
|
||||||
extern void rip_peer_bad_packet(struct sockaddr_in *);
|
extern void rip_peer_update(struct rip *rip, struct sockaddr_in *from,
|
||||||
extern void rip_peer_display(struct vty *);
|
uint8_t version);
|
||||||
extern struct rip_peer *rip_peer_lookup(struct in_addr *);
|
extern void rip_peer_bad_route(struct rip *rip, struct sockaddr_in *from);
|
||||||
extern struct rip_peer *rip_peer_lookup_next(struct in_addr *);
|
extern void rip_peer_bad_packet(struct rip *rip, struct sockaddr_in *from);
|
||||||
|
extern void rip_peer_display(struct vty *vty, struct rip *rip);
|
||||||
|
extern struct rip_peer *rip_peer_lookup(struct rip *rip, struct in_addr *addr);
|
||||||
|
extern struct rip_peer *rip_peer_lookup_next(struct rip *rip,
|
||||||
|
struct in_addr *addr);
|
||||||
|
extern int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2);
|
||||||
|
extern void rip_peer_list_del(void *arg);
|
||||||
|
|
||||||
extern void rip_info_free(struct rip_info *);
|
extern void rip_info_free(struct rip_info *);
|
||||||
|
extern struct rip *rip_info_get_instance(const struct rip_info *rinfo);
|
||||||
extern struct rip_distance *rip_distance_new(void);
|
extern struct rip_distance *rip_distance_new(void);
|
||||||
extern void rip_distance_free(struct rip_distance *rdistance);
|
extern void rip_distance_free(struct rip_distance *rdistance);
|
||||||
extern uint8_t rip_distance_apply(struct rip_info *);
|
extern uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo);
|
||||||
extern void rip_redistribute_clean(void);
|
extern void rip_redistribute_enable(struct rip *rip);
|
||||||
|
extern void rip_redistribute_disable(struct rip *rip);
|
||||||
|
|
||||||
extern int rip_route_rte(struct rip_info *rinfo);
|
extern int rip_route_rte(struct rip_info *rinfo);
|
||||||
extern struct rip_info *rip_ecmp_add(struct rip_info *);
|
extern struct rip_info *rip_ecmp_add(struct rip *rip,
|
||||||
extern struct rip_info *rip_ecmp_replace(struct rip_info *);
|
struct rip_info *rinfo_new);
|
||||||
extern struct rip_info *rip_ecmp_delete(struct rip_info *);
|
extern struct rip_info *rip_ecmp_replace(struct rip *rip,
|
||||||
|
struct rip_info *rinfo_new);
|
||||||
|
extern struct rip_info *rip_ecmp_delete(struct rip *rip,
|
||||||
|
struct rip_info *rinfo);
|
||||||
|
|
||||||
extern struct rip_offset_list *rip_offset_list_new(const char *ifname);
|
extern struct rip_offset_list *rip_offset_list_new(struct rip *rip,
|
||||||
|
const char *ifname);
|
||||||
extern void offset_list_del(struct rip_offset_list *offset);
|
extern void offset_list_del(struct rip_offset_list *offset);
|
||||||
extern struct rip_offset_list *rip_offset_list_lookup(const char *ifname);
|
extern struct rip_offset_list *rip_offset_list_lookup(struct rip *rip,
|
||||||
|
const char *ifname);
|
||||||
extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *,
|
extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *,
|
||||||
uint32_t *);
|
uint32_t *);
|
||||||
extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
|
extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
|
||||||
uint32_t *);
|
uint32_t *);
|
||||||
extern void rip_offset_init(void);
|
extern int offset_list_cmp(struct rip_offset_list *o1,
|
||||||
extern void rip_offset_clean(void);
|
struct rip_offset_list *o2);
|
||||||
|
|
||||||
|
extern void rip_vrf_init(void);
|
||||||
|
extern void rip_vrf_terminate(void);
|
||||||
|
|
||||||
/* YANG notifications */
|
/* YANG notifications */
|
||||||
extern void ripd_notif_send_auth_type_failure(const char *ifname);
|
extern void ripd_notif_send_auth_type_failure(const char *ifname);
|
||||||
extern void ripd_notif_send_auth_failure(const char *ifname);
|
extern void ripd_notif_send_auth_failure(const char *ifname);
|
||||||
|
|
||||||
/* There is only one rip strucutre. */
|
|
||||||
extern struct rip *rip;
|
|
||||||
|
|
||||||
extern struct zebra_privs_t ripd_privs;
|
extern struct zebra_privs_t ripd_privs;
|
||||||
|
extern struct rip_instance_head rip_instances;
|
||||||
|
|
||||||
/* Master thread strucutre. */
|
/* Master thread strucutre. */
|
||||||
extern struct thread_master *master;
|
extern struct thread_master *master;
|
||||||
|
|
||||||
/* RIP statistics for SNMP. */
|
|
||||||
extern long rip_global_route_changes;
|
|
||||||
extern long rip_global_queries;
|
|
||||||
|
|
||||||
DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc))
|
DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc))
|
||||||
DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
|
DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
|
||||||
|
|
||||||
extern struct list *peer_list;
|
|
||||||
extern struct route_table *rip_distance_table;
|
|
||||||
extern vector Vrip_passive_nondefault;
|
|
||||||
|
|
||||||
/* Northbound. */
|
/* Northbound. */
|
||||||
extern void rip_cli_init(void);
|
extern void rip_cli_init(void);
|
||||||
extern const struct frr_yang_module_info frr_ripd_info;
|
extern const struct frr_yang_module_info frr_ripd_info;
|
||||||
|
@ -39,31 +39,46 @@
|
|||||||
*/
|
*/
|
||||||
DEFPY_NOSH (router_ripng,
|
DEFPY_NOSH (router_ripng,
|
||||||
router_ripng_cmd,
|
router_ripng_cmd,
|
||||||
"router ripng",
|
"router ripng [vrf NAME]",
|
||||||
"Enable a routing process\n"
|
"Enable a routing process\n"
|
||||||
"Make RIPng instance command\n")
|
"Make RIPng instance command\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
|
char xpath[XPATH_MAXLEN];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_CREATE,
|
/* Build RIPng instance XPath. */
|
||||||
NULL);
|
if (!vrf)
|
||||||
|
vrf = VRF_DEFAULT_NAME;
|
||||||
|
snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/instance[vrf='%s']",
|
||||||
|
vrf);
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||||
|
|
||||||
ret = nb_cli_apply_changes(vty, NULL);
|
ret = nb_cli_apply_changes(vty, NULL);
|
||||||
if (ret == CMD_SUCCESS)
|
if (ret == CMD_SUCCESS)
|
||||||
VTY_PUSH_XPATH(RIPNG_NODE, "/frr-ripngd:ripngd/instance");
|
VTY_PUSH_XPATH(RIPNG_NODE, xpath);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFPY (no_router_ripng,
|
DEFPY (no_router_ripng,
|
||||||
no_router_ripng_cmd,
|
no_router_ripng_cmd,
|
||||||
"no router ripng",
|
"no router ripng [vrf NAME]",
|
||||||
NO_STR
|
NO_STR
|
||||||
"Enable a routing process\n"
|
"Enable a routing process\n"
|
||||||
"Make RIPng instance command\n")
|
"Make RIPng instance command\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_DESTROY,
|
char xpath[XPATH_MAXLEN];
|
||||||
NULL);
|
|
||||||
|
/* Build RIPng instance XPath. */
|
||||||
|
if (!vrf)
|
||||||
|
vrf = VRF_DEFAULT_NAME;
|
||||||
|
snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/instance[vrf='%s']",
|
||||||
|
vrf);
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||||
|
|
||||||
return nb_cli_apply_changes(vty, NULL);
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
}
|
}
|
||||||
@ -71,8 +86,15 @@ DEFPY (no_router_ripng,
|
|||||||
void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults)
|
bool show_defaults)
|
||||||
{
|
{
|
||||||
|
const char *vrf_name;
|
||||||
|
|
||||||
|
vrf_name = yang_dnode_get_string(dnode, "./vrf");
|
||||||
|
|
||||||
vty_out(vty, "!\n");
|
vty_out(vty, "!\n");
|
||||||
vty_out(vty, "router ripng\n");
|
vty_out(vty, "router ripng");
|
||||||
|
if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
|
||||||
|
vty_out(vty, " vrf %s", vrf_name);
|
||||||
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -456,12 +478,24 @@ void cli_show_ipv6_ripng_split_horizon(struct vty *vty, struct lyd_node *dnode,
|
|||||||
*/
|
*/
|
||||||
DEFPY (clear_ipv6_rip,
|
DEFPY (clear_ipv6_rip,
|
||||||
clear_ipv6_rip_cmd,
|
clear_ipv6_rip_cmd,
|
||||||
"clear ipv6 ripng",
|
"clear ipv6 ripng [vrf WORD]",
|
||||||
CLEAR_STR
|
CLEAR_STR
|
||||||
IPV6_STR
|
IPV6_STR
|
||||||
"Clear IPv6 RIP database\n")
|
"Clear IPv6 RIP database\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
return nb_cli_rpc("/frr-ripngd:clear-ripng-route", NULL, NULL);
|
struct list *input;
|
||||||
|
|
||||||
|
input = list_new();
|
||||||
|
if (vrf) {
|
||||||
|
struct yang_data *yang_vrf;
|
||||||
|
|
||||||
|
yang_vrf = yang_data_new(
|
||||||
|
"/frr-ripngd:clear-ripng-route/input/vrf", vrf);
|
||||||
|
listnode_add(input, yang_vrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nb_cli_rpc("/frr-ripngd:clear-ripng-route", input, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_cli_init(void)
|
void ripng_cli_init(void)
|
||||||
|
@ -52,12 +52,12 @@
|
|||||||
/* Static utility function. */
|
/* Static utility function. */
|
||||||
static void ripng_enable_apply(struct interface *);
|
static void ripng_enable_apply(struct interface *);
|
||||||
static void ripng_passive_interface_apply(struct interface *);
|
static void ripng_passive_interface_apply(struct interface *);
|
||||||
static int ripng_enable_if_lookup(const char *);
|
static int ripng_enable_if_lookup(struct ripng *ripng, const char *ifname);
|
||||||
static int ripng_enable_network_lookup2(struct connected *);
|
static int ripng_enable_network_lookup2(struct connected *);
|
||||||
static void ripng_enable_apply_all(void);
|
static void ripng_enable_apply_all(struct ripng *ripng);
|
||||||
|
|
||||||
/* Join to the all rip routers multicast group. */
|
/* Join to the all rip routers multicast group. */
|
||||||
static int ripng_multicast_join(struct interface *ifp)
|
static int ripng_multicast_join(struct interface *ifp, int sock)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct ipv6_mreq mreq;
|
struct ipv6_mreq mreq;
|
||||||
@ -75,8 +75,7 @@ static int ripng_multicast_join(struct interface *ifp)
|
|||||||
*/
|
*/
|
||||||
frr_elevate_privs(&ripngd_privs) {
|
frr_elevate_privs(&ripngd_privs) {
|
||||||
|
|
||||||
ret = setsockopt(ripng->sock, IPPROTO_IPV6,
|
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||||
IPV6_JOIN_GROUP,
|
|
||||||
(char *)&mreq, sizeof(mreq));
|
(char *)&mreq, sizeof(mreq));
|
||||||
save_errno = errno;
|
save_errno = errno;
|
||||||
|
|
||||||
@ -111,7 +110,7 @@ static int ripng_multicast_join(struct interface *ifp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Leave from the all rip routers multicast group. */
|
/* Leave from the all rip routers multicast group. */
|
||||||
static int ripng_multicast_leave(struct interface *ifp)
|
static int ripng_multicast_leave(struct interface *ifp, int sock)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct ipv6_mreq mreq;
|
struct ipv6_mreq mreq;
|
||||||
@ -121,7 +120,7 @@ static int ripng_multicast_leave(struct interface *ifp)
|
|||||||
inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
|
inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
|
||||||
mreq.ipv6mr_interface = ifp->ifindex;
|
mreq.ipv6mr_interface = ifp->ifindex;
|
||||||
|
|
||||||
ret = setsockopt(ripng->sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
|
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
|
||||||
(char *)&mreq, sizeof(mreq));
|
(char *)&mreq, sizeof(mreq));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
zlog_warn("can't setsockopt IPV6_LEAVE_GROUP: %s",
|
zlog_warn("can't setsockopt IPV6_LEAVE_GROUP: %s",
|
||||||
@ -163,9 +162,13 @@ static int ripng_if_down(struct interface *ifp)
|
|||||||
struct agg_node *rp;
|
struct agg_node *rp;
|
||||||
struct ripng_info *rinfo;
|
struct ripng_info *rinfo;
|
||||||
struct ripng_interface *ri;
|
struct ripng_interface *ri;
|
||||||
|
struct ripng *ripng;
|
||||||
struct list *list = NULL;
|
struct list *list = NULL;
|
||||||
struct listnode *listnode = NULL, *nextnode = NULL;
|
struct listnode *listnode = NULL, *nextnode = NULL;
|
||||||
|
|
||||||
|
ri = ifp->info;
|
||||||
|
ripng = ri->ripng;
|
||||||
|
|
||||||
if (ripng)
|
if (ripng)
|
||||||
for (rp = agg_route_top(ripng->table); rp;
|
for (rp = agg_route_top(ripng->table); rp;
|
||||||
rp = agg_route_next(rp))
|
rp = agg_route_next(rp))
|
||||||
@ -173,16 +176,15 @@ static int ripng_if_down(struct interface *ifp)
|
|||||||
for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
|
for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
|
||||||
rinfo))
|
rinfo))
|
||||||
if (rinfo->ifindex == ifp->ifindex)
|
if (rinfo->ifindex == ifp->ifindex)
|
||||||
ripng_ecmp_delete(rinfo);
|
ripng_ecmp_delete(ripng, rinfo);
|
||||||
|
|
||||||
ri = ifp->info;
|
|
||||||
|
|
||||||
if (ri->running) {
|
if (ri->running) {
|
||||||
if (IS_RIPNG_DEBUG_EVENT)
|
if (IS_RIPNG_DEBUG_EVENT)
|
||||||
zlog_debug("turn off %s", ifp->name);
|
zlog_debug("turn off %s", ifp->name);
|
||||||
|
|
||||||
/* Leave from multicast group. */
|
/* Leave from multicast group. */
|
||||||
ripng_multicast_leave(ifp);
|
ripng_multicast_leave(ifp, ripng->sock);
|
||||||
|
|
||||||
ri->running = 0;
|
ri->running = 0;
|
||||||
}
|
}
|
||||||
@ -207,9 +209,11 @@ int ripng_interface_up(int command, struct zclient *zclient,
|
|||||||
|
|
||||||
if (IS_RIPNG_DEBUG_ZEBRA)
|
if (IS_RIPNG_DEBUG_ZEBRA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"interface up %s index %d flags %llx metric %d mtu %d",
|
"interface up %s vrf %u index %d flags %llx metric %d mtu %d",
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
ifp->metric, ifp->mtu6);
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
|
||||||
|
|
||||||
|
ripng_interface_sync(ifp);
|
||||||
|
|
||||||
/* Check if this interface is RIPng enabled or not. */
|
/* Check if this interface is RIPng enabled or not. */
|
||||||
ripng_enable_apply(ifp);
|
ripng_enable_apply(ifp);
|
||||||
@ -238,13 +242,14 @@ int ripng_interface_down(int command, struct zclient *zclient,
|
|||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
ripng_interface_sync(ifp);
|
||||||
ripng_if_down(ifp);
|
ripng_if_down(ifp);
|
||||||
|
|
||||||
if (IS_RIPNG_DEBUG_ZEBRA)
|
if (IS_RIPNG_DEBUG_ZEBRA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"interface down %s index %d flags %#llx metric %d mtu %d",
|
"interface down %s vrf %u index %d flags %#llx metric %d mtu %d",
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
ifp->metric, ifp->mtu6);
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -256,12 +261,13 @@ int ripng_interface_add(int command, struct zclient *zclient,
|
|||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
|
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
|
||||||
|
ripng_interface_sync(ifp);
|
||||||
|
|
||||||
if (IS_RIPNG_DEBUG_ZEBRA)
|
if (IS_RIPNG_DEBUG_ZEBRA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"RIPng interface add %s index %d flags %#llx metric %d mtu %d",
|
"RIPng interface add %s vrf %u index %d flags %#llx metric %d mtu %d",
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
ifp->metric, ifp->mtu6);
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
|
||||||
|
|
||||||
/* Check is this interface is RIP enabled or not.*/
|
/* Check is this interface is RIP enabled or not.*/
|
||||||
ripng_enable_apply(ifp);
|
ripng_enable_apply(ifp);
|
||||||
@ -289,13 +295,15 @@ int ripng_interface_delete(int command, struct zclient *zclient,
|
|||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
ripng_interface_sync(ifp);
|
||||||
if (if_is_up(ifp)) {
|
if (if_is_up(ifp)) {
|
||||||
ripng_if_down(ifp);
|
ripng_if_down(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
|
zlog_info(
|
||||||
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
|
"interface delete %s vrf %u index %d flags %#llx metric %d mtu %d",
|
||||||
ifp->metric, ifp->mtu6);
|
ifp->name, ifp->vrf_id, ifp->ifindex,
|
||||||
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
|
||||||
|
|
||||||
/* To support pseudo interface do not free interface structure. */
|
/* To support pseudo interface do not free interface structure. */
|
||||||
/* if_delete(ifp); */
|
/* if_delete(ifp); */
|
||||||
@ -304,13 +312,34 @@ int ripng_interface_delete(int command, struct zclient *zclient,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_interface_clean(void)
|
/* VRF update for an interface. */
|
||||||
|
int ripng_interface_vrf_update(int command, struct zclient *zclient,
|
||||||
|
zebra_size_t length, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
vrf_id_t new_vrf_id;
|
||||||
|
|
||||||
|
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
|
||||||
|
&new_vrf_id);
|
||||||
|
if (!ifp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (IS_RIPNG_DEBUG_ZEBRA)
|
||||||
|
zlog_debug("interface %s VRF change vrf_id %u new vrf id %u",
|
||||||
|
ifp->name, vrf_id, new_vrf_id);
|
||||||
|
|
||||||
|
if_update_to_new_vrf(ifp, new_vrf_id);
|
||||||
|
ripng_interface_sync(ifp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ripng_interface_clean(struct ripng *ripng)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct ripng_interface *ri;
|
struct ripng_interface *ri;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp) {
|
FOR_ALL_INTERFACES (ripng->vrf, ifp) {
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
|
|
||||||
ri->enable_network = 0;
|
ri->enable_network = 0;
|
||||||
@ -326,6 +355,8 @@ void ripng_interface_clean(void)
|
|||||||
|
|
||||||
static void ripng_apply_address_add(struct connected *ifc)
|
static void ripng_apply_address_add(struct connected *ifc)
|
||||||
{
|
{
|
||||||
|
struct ripng_interface *ri = ifc->ifp->info;
|
||||||
|
struct ripng *ripng = ri->ripng;
|
||||||
struct prefix_ipv6 address;
|
struct prefix_ipv6 address;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
|
||||||
@ -345,9 +376,9 @@ static void ripng_apply_address_add(struct connected *ifc)
|
|||||||
|
|
||||||
/* Check if this interface is RIP enabled or not
|
/* Check if this interface is RIP enabled or not
|
||||||
or Check if this address's prefix is RIP enabled */
|
or Check if this address's prefix is RIP enabled */
|
||||||
if ((ripng_enable_if_lookup(ifc->ifp->name) >= 0)
|
if ((ripng_enable_if_lookup(ripng, ifc->ifp->name) >= 0)
|
||||||
|| (ripng_enable_network_lookup2(ifc) >= 0))
|
|| (ripng_enable_network_lookup2(ifc) >= 0))
|
||||||
ripng_redistribute_add(ZEBRA_ROUTE_CONNECT,
|
ripng_redistribute_add(ripng, ZEBRA_ROUTE_CONNECT,
|
||||||
RIPNG_ROUTE_INTERFACE, &address,
|
RIPNG_ROUTE_INTERFACE, &address,
|
||||||
ifc->ifp->ifindex, NULL, 0);
|
ifc->ifp->ifindex, NULL, 0);
|
||||||
}
|
}
|
||||||
@ -395,6 +426,8 @@ int ripng_interface_address_add(int command, struct zclient *zclient,
|
|||||||
|
|
||||||
static void ripng_apply_address_del(struct connected *ifc)
|
static void ripng_apply_address_del(struct connected *ifc)
|
||||||
{
|
{
|
||||||
|
struct ripng_interface *ri = ifc->ifp->info;
|
||||||
|
struct ripng *ripng = ri->ripng;
|
||||||
struct prefix_ipv6 address;
|
struct prefix_ipv6 address;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
|
||||||
@ -412,8 +445,9 @@ static void ripng_apply_address_del(struct connected *ifc)
|
|||||||
address.prefixlen = p->prefixlen;
|
address.prefixlen = p->prefixlen;
|
||||||
apply_mask_ipv6(&address);
|
apply_mask_ipv6(&address);
|
||||||
|
|
||||||
ripng_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_INTERFACE,
|
ripng_redistribute_delete(ripng, ZEBRA_ROUTE_CONNECT,
|
||||||
&address, ifc->ifp->ifindex);
|
RIPNG_ROUTE_INTERFACE, &address,
|
||||||
|
ifc->ifp->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ripng_interface_address_delete(int command, struct zclient *zclient,
|
int ripng_interface_address_delete(int command, struct zclient *zclient,
|
||||||
@ -446,21 +480,20 @@ int ripng_interface_address_delete(int command, struct zclient *zclient,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RIPng enable interface vector. */
|
|
||||||
vector ripng_enable_if;
|
|
||||||
|
|
||||||
/* RIPng enable network table. */
|
|
||||||
struct agg_table *ripng_enable_network;
|
|
||||||
|
|
||||||
/* Lookup RIPng enable network. */
|
/* Lookup RIPng enable network. */
|
||||||
/* Check wether the interface has at least a connected prefix that
|
/* Check wether the interface has at least a connected prefix that
|
||||||
* is within the ripng_enable_network table. */
|
* is within the ripng->enable_network table. */
|
||||||
static int ripng_enable_network_lookup_if(struct interface *ifp)
|
static int ripng_enable_network_lookup_if(struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
struct ripng_interface *ri = ifp->info;
|
||||||
|
struct ripng *ripng = ri->ripng;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct connected *connected;
|
struct connected *connected;
|
||||||
struct prefix_ipv6 address;
|
struct prefix_ipv6 address;
|
||||||
|
|
||||||
|
if (!ripng)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
struct agg_node *n;
|
struct agg_node *n;
|
||||||
@ -472,7 +505,7 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
|
|||||||
address.prefix = p->u.prefix6;
|
address.prefix = p->u.prefix6;
|
||||||
address.prefixlen = IPV6_MAX_BITLEN;
|
address.prefixlen = IPV6_MAX_BITLEN;
|
||||||
|
|
||||||
n = agg_node_match(ripng_enable_network,
|
n = agg_node_match(ripng->enable_network,
|
||||||
(struct prefix *)&address);
|
(struct prefix *)&address);
|
||||||
if (n) {
|
if (n) {
|
||||||
agg_unlock_node(n);
|
agg_unlock_node(n);
|
||||||
@ -483,12 +516,17 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check wether connected is within the ripng_enable_network table. */
|
/* Check wether connected is within the ripng->enable_network table. */
|
||||||
static int ripng_enable_network_lookup2(struct connected *connected)
|
static int ripng_enable_network_lookup2(struct connected *connected)
|
||||||
{
|
{
|
||||||
|
struct ripng_interface *ri = connected->ifp->info;
|
||||||
|
struct ripng *ripng = ri->ripng;
|
||||||
struct prefix_ipv6 address;
|
struct prefix_ipv6 address;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
|
||||||
|
if (!ripng)
|
||||||
|
return -1;
|
||||||
|
|
||||||
p = connected->address;
|
p = connected->address;
|
||||||
|
|
||||||
if (p->family == AF_INET6) {
|
if (p->family == AF_INET6) {
|
||||||
@ -499,8 +537,8 @@ static int ripng_enable_network_lookup2(struct connected *connected)
|
|||||||
address.prefixlen = IPV6_MAX_BITLEN;
|
address.prefixlen = IPV6_MAX_BITLEN;
|
||||||
|
|
||||||
/* LPM on p->family, p->u.prefix6/IPV6_MAX_BITLEN within
|
/* LPM on p->family, p->u.prefix6/IPV6_MAX_BITLEN within
|
||||||
* ripng_enable_network */
|
* ripng->enable_network */
|
||||||
node = agg_node_match(ripng_enable_network,
|
node = agg_node_match(ripng->enable_network,
|
||||||
(struct prefix *)&address);
|
(struct prefix *)&address);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
@ -513,11 +551,11 @@ static int ripng_enable_network_lookup2(struct connected *connected)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add RIPng enable network. */
|
/* Add RIPng enable network. */
|
||||||
int ripng_enable_network_add(struct prefix *p)
|
int ripng_enable_network_add(struct ripng *ripng, struct prefix *p)
|
||||||
{
|
{
|
||||||
struct agg_node *node;
|
struct agg_node *node;
|
||||||
|
|
||||||
node = agg_node_get(ripng_enable_network, p);
|
node = agg_node_get(ripng->enable_network, p);
|
||||||
|
|
||||||
if (node->info) {
|
if (node->info) {
|
||||||
agg_unlock_node(node);
|
agg_unlock_node(node);
|
||||||
@ -526,17 +564,17 @@ int ripng_enable_network_add(struct prefix *p)
|
|||||||
node->info = (void *)1;
|
node->info = (void *)1;
|
||||||
|
|
||||||
/* XXX: One should find a better solution than a generic one */
|
/* XXX: One should find a better solution than a generic one */
|
||||||
ripng_enable_apply_all();
|
ripng_enable_apply_all(ripng);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete RIPng enable network. */
|
/* Delete RIPng enable network. */
|
||||||
int ripng_enable_network_delete(struct prefix *p)
|
int ripng_enable_network_delete(struct ripng *ripng, struct prefix *p)
|
||||||
{
|
{
|
||||||
struct agg_node *node;
|
struct agg_node *node;
|
||||||
|
|
||||||
node = agg_node_lookup(ripng_enable_network, p);
|
node = agg_node_lookup(ripng->enable_network, p);
|
||||||
if (node) {
|
if (node) {
|
||||||
node->info = NULL;
|
node->info = NULL;
|
||||||
|
|
||||||
@ -553,49 +591,50 @@ int ripng_enable_network_delete(struct prefix *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup function. */
|
/* Lookup function. */
|
||||||
static int ripng_enable_if_lookup(const char *ifname)
|
static int ripng_enable_if_lookup(struct ripng *ripng, const char *ifname)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for (i = 0; i < vector_active(ripng_enable_if); i++)
|
if (!ripng)
|
||||||
if ((str = vector_slot(ripng_enable_if, i)) != NULL)
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < vector_active(ripng->enable_if); i++)
|
||||||
|
if ((str = vector_slot(ripng->enable_if, i)) != NULL)
|
||||||
if (strcmp(str, ifname) == 0)
|
if (strcmp(str, ifname) == 0)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add interface to ripng_enable_if. */
|
int ripng_enable_if_add(struct ripng *ripng, const char *ifname)
|
||||||
int ripng_enable_if_add(const char *ifname)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ripng_enable_if_lookup(ifname);
|
ret = ripng_enable_if_lookup(ripng, ifname);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
return NB_ERR_INCONSISTENCY;
|
return NB_ERR_INCONSISTENCY;
|
||||||
|
|
||||||
vector_set(ripng_enable_if, strdup(ifname));
|
vector_set(ripng->enable_if, strdup(ifname));
|
||||||
|
|
||||||
ripng_enable_apply_all();
|
ripng_enable_apply_all(ripng);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete interface from ripng_enable_if. */
|
int ripng_enable_if_delete(struct ripng *ripng, const char *ifname)
|
||||||
int ripng_enable_if_delete(const char *ifname)
|
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
index = ripng_enable_if_lookup(ifname);
|
index = ripng_enable_if_lookup(ripng, ifname);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return NB_ERR_INCONSISTENCY;
|
return NB_ERR_INCONSISTENCY;
|
||||||
|
|
||||||
str = vector_slot(ripng_enable_if, index);
|
str = vector_slot(ripng->enable_if, index);
|
||||||
free(str);
|
free(str);
|
||||||
vector_unset(ripng_enable_if, index);
|
vector_unset(ripng->enable_if, index);
|
||||||
|
|
||||||
ripng_enable_apply_all();
|
ripng_enable_apply_all(ripng);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -613,7 +652,7 @@ static int ripng_interface_wakeup(struct thread *t)
|
|||||||
ri->t_wakeup = NULL;
|
ri->t_wakeup = NULL;
|
||||||
|
|
||||||
/* Join to multicast group. */
|
/* Join to multicast group. */
|
||||||
if (ripng_multicast_join(ifp) < 0) {
|
if (ripng_multicast_join(ifp, ri->ripng->sock) < 0) {
|
||||||
flog_err_sys(EC_LIB_SOCKET,
|
flog_err_sys(EC_LIB_SOCKET,
|
||||||
"multicast join failed, interface %s not running",
|
"multicast join failed, interface %s not running",
|
||||||
ifp->name);
|
ifp->name);
|
||||||
@ -631,6 +670,8 @@ static int ripng_interface_wakeup(struct thread *t)
|
|||||||
|
|
||||||
static void ripng_connect_set(struct interface *ifp, int set)
|
static void ripng_connect_set(struct interface *ifp, int set)
|
||||||
{
|
{
|
||||||
|
struct ripng_interface *ri = ifp->info;
|
||||||
|
struct ripng *ripng = ri->ripng;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct connected *connected;
|
struct connected *connected;
|
||||||
struct prefix_ipv6 address;
|
struct prefix_ipv6 address;
|
||||||
@ -650,19 +691,22 @@ static void ripng_connect_set(struct interface *ifp, int set)
|
|||||||
if (set) {
|
if (set) {
|
||||||
/* Check once more wether this prefix is within a
|
/* Check once more wether this prefix is within a
|
||||||
* "network IF_OR_PREF" one */
|
* "network IF_OR_PREF" one */
|
||||||
if ((ripng_enable_if_lookup(connected->ifp->name) >= 0)
|
if ((ripng_enable_if_lookup(ripng, connected->ifp->name)
|
||||||
|
>= 0)
|
||||||
|| (ripng_enable_network_lookup2(connected) >= 0))
|
|| (ripng_enable_network_lookup2(connected) >= 0))
|
||||||
ripng_redistribute_add(
|
ripng_redistribute_add(
|
||||||
ZEBRA_ROUTE_CONNECT,
|
ripng, ZEBRA_ROUTE_CONNECT,
|
||||||
RIPNG_ROUTE_INTERFACE, &address,
|
RIPNG_ROUTE_INTERFACE, &address,
|
||||||
connected->ifp->ifindex, NULL, 0);
|
connected->ifp->ifindex, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
ripng_redistribute_delete(
|
ripng_redistribute_delete(ripng, ZEBRA_ROUTE_CONNECT,
|
||||||
ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_INTERFACE,
|
RIPNG_ROUTE_INTERFACE,
|
||||||
&address, connected->ifp->ifindex);
|
&address,
|
||||||
if (ripng_redistribute_check(ZEBRA_ROUTE_CONNECT))
|
connected->ifp->ifindex);
|
||||||
|
if (ripng_redistribute_check(ripng,
|
||||||
|
ZEBRA_ROUTE_CONNECT))
|
||||||
ripng_redistribute_add(
|
ripng_redistribute_add(
|
||||||
ZEBRA_ROUTE_CONNECT,
|
ripng, ZEBRA_ROUTE_CONNECT,
|
||||||
RIPNG_ROUTE_REDISTRIBUTE, &address,
|
RIPNG_ROUTE_REDISTRIBUTE, &address,
|
||||||
connected->ifp->ifindex, NULL, 0);
|
connected->ifp->ifindex, NULL, 0);
|
||||||
}
|
}
|
||||||
@ -691,7 +735,7 @@ void ripng_enable_apply(struct interface *ifp)
|
|||||||
ri->enable_network = 0;
|
ri->enable_network = 0;
|
||||||
|
|
||||||
/* Check interface name configuration. */
|
/* Check interface name configuration. */
|
||||||
ret = ripng_enable_if_lookup(ifp->name);
|
ret = ripng_enable_if_lookup(ri->ripng, ifp->name);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
ri->enable_interface = 1;
|
ri->enable_interface = 1;
|
||||||
else
|
else
|
||||||
@ -729,49 +773,46 @@ void ripng_enable_apply(struct interface *ifp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set distribute list to all interfaces. */
|
/* Set distribute list to all interfaces. */
|
||||||
static void ripng_enable_apply_all(void)
|
static void ripng_enable_apply_all(struct ripng *ripng)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
FOR_ALL_INTERFACES (ripng->vrf, ifp)
|
||||||
ripng_enable_apply(ifp);
|
ripng_enable_apply(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear all network and neighbor configuration */
|
/* Clear all network and neighbor configuration */
|
||||||
void ripng_clean_network(void)
|
void ripng_clean_network(struct ripng *ripng)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
struct agg_node *rn;
|
struct agg_node *rn;
|
||||||
|
|
||||||
/* ripng_enable_network */
|
/* ripng->enable_network */
|
||||||
for (rn = agg_route_top(ripng_enable_network); rn;
|
for (rn = agg_route_top(ripng->enable_network); rn;
|
||||||
rn = agg_route_next(rn))
|
rn = agg_route_next(rn))
|
||||||
if (rn->info) {
|
if (rn->info) {
|
||||||
rn->info = NULL;
|
rn->info = NULL;
|
||||||
agg_unlock_node(rn);
|
agg_unlock_node(rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ripng_enable_if */
|
/* ripng->enable_if */
|
||||||
for (i = 0; i < vector_active(ripng_enable_if); i++)
|
for (i = 0; i < vector_active(ripng->enable_if); i++)
|
||||||
if ((str = vector_slot(ripng_enable_if, i)) != NULL) {
|
if ((str = vector_slot(ripng->enable_if, i)) != NULL) {
|
||||||
free(str);
|
free(str);
|
||||||
vector_slot(ripng_enable_if, i) = NULL;
|
vector_slot(ripng->enable_if, i) = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vector to store passive-interface name. */
|
|
||||||
vector Vripng_passive_interface;
|
|
||||||
|
|
||||||
/* Utility function for looking up passive interface settings. */
|
/* Utility function for looking up passive interface settings. */
|
||||||
static int ripng_passive_interface_lookup(const char *ifname)
|
static int ripng_passive_interface_lookup(struct ripng *ripng,
|
||||||
|
const char *ifname)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for (i = 0; i < vector_active(Vripng_passive_interface); i++)
|
for (i = 0; i < vector_active(ripng->passive_interface); i++)
|
||||||
if ((str = vector_slot(Vripng_passive_interface, i)) != NULL)
|
if ((str = vector_slot(ripng->passive_interface, i)) != NULL)
|
||||||
if (strcmp(str, ifname) == 0)
|
if (strcmp(str, ifname) == 0)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
@ -781,72 +822,75 @@ void ripng_passive_interface_apply(struct interface *ifp)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct ripng_interface *ri;
|
struct ripng_interface *ri;
|
||||||
|
struct ripng *ripng;
|
||||||
|
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
|
ripng = ri->ripng;
|
||||||
|
if (!ripng)
|
||||||
|
return;
|
||||||
|
|
||||||
ret = ripng_passive_interface_lookup(ifp->name);
|
ret = ripng_passive_interface_lookup(ripng, ifp->name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
ri->passive = 0;
|
ri->passive = 0;
|
||||||
else
|
else
|
||||||
ri->passive = 1;
|
ri->passive = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ripng_passive_interface_apply_all(void)
|
static void ripng_passive_interface_apply_all(struct ripng *ripng)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
FOR_ALL_INTERFACES (ripng->vrf, ifp)
|
||||||
ripng_passive_interface_apply(ifp);
|
ripng_passive_interface_apply(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Passive interface. */
|
/* Passive interface. */
|
||||||
int ripng_passive_interface_set(const char *ifname)
|
int ripng_passive_interface_set(struct ripng *ripng, const char *ifname)
|
||||||
{
|
{
|
||||||
if (ripng_passive_interface_lookup(ifname) >= 0)
|
if (ripng_passive_interface_lookup(ripng, ifname) >= 0)
|
||||||
return NB_ERR_INCONSISTENCY;
|
return NB_ERR_INCONSISTENCY;
|
||||||
|
|
||||||
vector_set(Vripng_passive_interface, strdup(ifname));
|
vector_set(ripng->passive_interface, strdup(ifname));
|
||||||
|
|
||||||
ripng_passive_interface_apply_all();
|
ripng_passive_interface_apply_all(ripng);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ripng_passive_interface_unset(const char *ifname)
|
int ripng_passive_interface_unset(struct ripng *ripng, const char *ifname)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
i = ripng_passive_interface_lookup(ifname);
|
i = ripng_passive_interface_lookup(ripng, ifname);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return NB_ERR_INCONSISTENCY;
|
return NB_ERR_INCONSISTENCY;
|
||||||
|
|
||||||
str = vector_slot(Vripng_passive_interface, i);
|
str = vector_slot(ripng->passive_interface, i);
|
||||||
free(str);
|
free(str);
|
||||||
vector_unset(Vripng_passive_interface, i);
|
vector_unset(ripng->passive_interface, i);
|
||||||
|
|
||||||
ripng_passive_interface_apply_all();
|
ripng_passive_interface_apply_all(ripng);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free all configured RIP passive-interface settings. */
|
/* Free all configured RIP passive-interface settings. */
|
||||||
void ripng_passive_interface_clean(void)
|
void ripng_passive_interface_clean(struct ripng *ripng)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for (i = 0; i < vector_active(Vripng_passive_interface); i++)
|
for (i = 0; i < vector_active(ripng->passive_interface); i++)
|
||||||
if ((str = vector_slot(Vripng_passive_interface, i)) != NULL) {
|
if ((str = vector_slot(ripng->passive_interface, i)) != NULL) {
|
||||||
free(str);
|
free(str);
|
||||||
vector_slot(Vripng_passive_interface, i) = NULL;
|
vector_slot(ripng->passive_interface, i) = NULL;
|
||||||
}
|
}
|
||||||
ripng_passive_interface_apply_all();
|
ripng_passive_interface_apply_all(ripng);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write RIPng enable network and interface to the vty. */
|
/* Write RIPng enable network and interface to the vty. */
|
||||||
int ripng_network_write(struct vty *vty)
|
int ripng_network_write(struct vty *vty, struct ripng *ripng)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *ifname;
|
const char *ifname;
|
||||||
@ -854,7 +898,7 @@ int ripng_network_write(struct vty *vty)
|
|||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
/* Write enable network. */
|
/* Write enable network. */
|
||||||
for (node = agg_route_top(ripng_enable_network); node;
|
for (node = agg_route_top(ripng->enable_network); node;
|
||||||
node = agg_route_next(node))
|
node = agg_route_next(node))
|
||||||
if (node->info) {
|
if (node->info) {
|
||||||
struct prefix *p = &node->p;
|
struct prefix *p = &node->p;
|
||||||
@ -864,8 +908,8 @@ int ripng_network_write(struct vty *vty)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write enable interface. */
|
/* Write enable interface. */
|
||||||
for (i = 0; i < vector_active(ripng_enable_if); i++)
|
for (i = 0; i < vector_active(ripng->enable_if); i++)
|
||||||
if ((ifname = vector_slot(ripng_enable_if, i)) != NULL)
|
if ((ifname = vector_slot(ripng->enable_if, i)) != NULL)
|
||||||
vty_out(vty, " %s\n", ifname);
|
vty_out(vty, " %s\n", ifname);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -874,6 +918,7 @@ int ripng_network_write(struct vty *vty)
|
|||||||
static struct ripng_interface *ri_new(void)
|
static struct ripng_interface *ri_new(void)
|
||||||
{
|
{
|
||||||
struct ripng_interface *ri;
|
struct ripng_interface *ri;
|
||||||
|
|
||||||
ri = XCALLOC(MTYPE_IF, sizeof(struct ripng_interface));
|
ri = XCALLOC(MTYPE_IF, sizeof(struct ripng_interface));
|
||||||
|
|
||||||
/* Set default split-horizon behavior. If the interface is Frame
|
/* Set default split-horizon behavior. If the interface is Frame
|
||||||
@ -886,9 +931,25 @@ static struct ripng_interface *ri_new(void)
|
|||||||
return ri;
|
return ri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ripng_interface_sync(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
vrf = vrf_lookup_by_id(ifp->vrf_id);
|
||||||
|
if (vrf) {
|
||||||
|
struct ripng_interface *ri;
|
||||||
|
|
||||||
|
ri = ifp->info;
|
||||||
|
if (ri)
|
||||||
|
ri->ripng = vrf->info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ripng_if_new_hook(struct interface *ifp)
|
static int ripng_if_new_hook(struct interface *ifp)
|
||||||
{
|
{
|
||||||
ifp->info = ri_new();
|
ifp->info = ri_new();
|
||||||
|
ripng_interface_sync(ifp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,22 +964,25 @@ static int ripng_if_delete_hook(struct interface *ifp)
|
|||||||
/* Configuration write function for ripngd. */
|
/* Configuration write function for ripngd. */
|
||||||
static int interface_config_write(struct vty *vty)
|
static int interface_config_write(struct vty *vty)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
struct vrf *vrf;
|
||||||
struct interface *ifp;
|
|
||||||
int write = 0;
|
int write = 0;
|
||||||
|
|
||||||
FOR_ALL_INTERFACES (vrf, ifp) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||||
struct lyd_node *dnode;
|
struct interface *ifp;
|
||||||
|
|
||||||
dnode = yang_dnode_get(
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
||||||
running_config->dnode,
|
struct lyd_node *dnode;
|
||||||
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
|
|
||||||
ifp->name, vrf->name);
|
|
||||||
if (dnode == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
write = 1;
|
dnode = yang_dnode_get(
|
||||||
nb_cli_show_dnode_cmds(vty, dnode, false);
|
running_config->dnode,
|
||||||
|
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
|
||||||
|
ifp->name, vrf->name);
|
||||||
|
if (dnode == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
write = 1;
|
||||||
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
@ -936,15 +1000,6 @@ void ripng_if_init(void)
|
|||||||
hook_register_prio(if_add, 0, ripng_if_new_hook);
|
hook_register_prio(if_add, 0, ripng_if_new_hook);
|
||||||
hook_register_prio(if_del, 0, ripng_if_delete_hook);
|
hook_register_prio(if_del, 0, ripng_if_delete_hook);
|
||||||
|
|
||||||
/* RIPng enable network init. */
|
|
||||||
ripng_enable_network = agg_table_init();
|
|
||||||
|
|
||||||
/* RIPng enable interface init. */
|
|
||||||
ripng_enable_if = vector_init(1);
|
|
||||||
|
|
||||||
/* RIPng passive interface. */
|
|
||||||
Vripng_passive_interface = vector_init(1);
|
|
||||||
|
|
||||||
/* Install interface node. */
|
/* Install interface node. */
|
||||||
install_node(&interface_node, interface_config_write);
|
install_node(&interface_node, interface_config_write);
|
||||||
if_cmd_init();
|
if_cmd_init();
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
#include "vrf.h"
|
#include "vrf.h"
|
||||||
|
#include "if_rmap.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
|
|
||||||
#include "ripngd/ripngd.h"
|
#include "ripngd/ripngd.h"
|
||||||
@ -46,7 +47,7 @@
|
|||||||
struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};
|
struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};
|
||||||
|
|
||||||
/* ripngd privileges */
|
/* ripngd privileges */
|
||||||
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND};
|
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
|
||||||
|
|
||||||
struct zebra_privs_t ripngd_privs = {
|
struct zebra_privs_t ripngd_privs = {
|
||||||
#if defined(FRR_USER)
|
#if defined(FRR_USER)
|
||||||
@ -59,7 +60,7 @@ struct zebra_privs_t ripngd_privs = {
|
|||||||
.vty_group = VTY_GROUP,
|
.vty_group = VTY_GROUP,
|
||||||
#endif
|
#endif
|
||||||
.caps_p = _caps_p,
|
.caps_p = _caps_p,
|
||||||
.cap_num_p = 2,
|
.cap_num_p = array_size(_caps_p),
|
||||||
.cap_num_i = 0};
|
.cap_num_i = 0};
|
||||||
|
|
||||||
|
|
||||||
@ -82,8 +83,8 @@ static void sigint(void)
|
|||||||
{
|
{
|
||||||
zlog_notice("Terminating on signal");
|
zlog_notice("Terminating on signal");
|
||||||
|
|
||||||
ripng_clean();
|
ripng_vrf_terminate();
|
||||||
|
if_rmap_terminate();
|
||||||
ripng_zebra_stop();
|
ripng_zebra_stop();
|
||||||
frr_fini();
|
frr_fini();
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -170,13 +171,12 @@ int main(int argc, char **argv)
|
|||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
|
||||||
/* Library inits. */
|
/* Library inits. */
|
||||||
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
ripng_vrf_init();
|
||||||
|
|
||||||
/* RIPngd inits. */
|
/* RIPngd inits. */
|
||||||
ripng_init();
|
ripng_init();
|
||||||
ripng_cli_init();
|
ripng_cli_init();
|
||||||
zebra_init(master);
|
zebra_init(master);
|
||||||
ripng_peer_init();
|
|
||||||
|
|
||||||
frr_config_fork();
|
frr_config_fork();
|
||||||
frr_run(master);
|
frr_run(master);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
DEFINE_MGROUP(RIPNGD, "ripngd")
|
DEFINE_MGROUP(RIPNGD, "ripngd")
|
||||||
DEFINE_MTYPE(RIPNGD, RIPNG, "RIPng structure")
|
DEFINE_MTYPE(RIPNGD, RIPNG, "RIPng structure")
|
||||||
|
DEFINE_MTYPE(RIPNGD, RIPNG_VRF_NAME, "RIPng VRF name")
|
||||||
DEFINE_MTYPE(RIPNGD, RIPNG_ROUTE, "RIPng route info")
|
DEFINE_MTYPE(RIPNGD, RIPNG_ROUTE, "RIPng route info")
|
||||||
DEFINE_MTYPE(RIPNGD, RIPNG_AGGREGATE, "RIPng aggregate")
|
DEFINE_MTYPE(RIPNGD, RIPNG_AGGREGATE, "RIPng aggregate")
|
||||||
DEFINE_MTYPE(RIPNGD, RIPNG_PEER, "RIPng peer")
|
DEFINE_MTYPE(RIPNGD, RIPNG_PEER, "RIPng peer")
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
DECLARE_MGROUP(RIPNGD)
|
DECLARE_MGROUP(RIPNGD)
|
||||||
DECLARE_MTYPE(RIPNG)
|
DECLARE_MTYPE(RIPNG)
|
||||||
|
DECLARE_MTYPE(RIPNG_VRF_NAME)
|
||||||
DECLARE_MTYPE(RIPNG_ROUTE)
|
DECLARE_MTYPE(RIPNG_ROUTE)
|
||||||
DECLARE_MTYPE(RIPNG_AGGREGATE)
|
DECLARE_MTYPE(RIPNG_AGGREGATE)
|
||||||
DECLARE_MTYPE(RIPNG_PEER)
|
DECLARE_MTYPE(RIPNG_PEER)
|
||||||
|
@ -114,7 +114,8 @@ void ripng_rte_add(struct list *ripng_rte_list, struct prefix_ipv6 *p,
|
|||||||
void ripng_rte_send(struct list *ripng_rte_list, struct interface *ifp,
|
void ripng_rte_send(struct list *ripng_rte_list, struct interface *ifp,
|
||||||
struct sockaddr_in6 *to)
|
struct sockaddr_in6 *to)
|
||||||
{
|
{
|
||||||
|
struct ripng_interface *ri = ifp->info;
|
||||||
|
struct ripng *ripng = ri->ripng;
|
||||||
struct ripng_rte_data *data;
|
struct ripng_rte_data *data;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,29 +33,29 @@
|
|||||||
|
|
||||||
#include "ripngd/ripngd.h"
|
#include "ripngd/ripngd.h"
|
||||||
|
|
||||||
static struct list *ripng_offset_list_master;
|
|
||||||
|
|
||||||
#define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
|
#define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
|
||||||
#define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
|
#define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
|
||||||
|
|
||||||
#define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
|
#define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
|
||||||
#define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
|
#define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
|
||||||
|
|
||||||
struct ripng_offset_list *ripng_offset_list_new(const char *ifname)
|
struct ripng_offset_list *ripng_offset_list_new(struct ripng *ripng,
|
||||||
|
const char *ifname)
|
||||||
{
|
{
|
||||||
struct ripng_offset_list *new;
|
struct ripng_offset_list *new;
|
||||||
|
|
||||||
new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST,
|
new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST,
|
||||||
sizeof(struct ripng_offset_list));
|
sizeof(struct ripng_offset_list));
|
||||||
|
new->ripng = ripng;
|
||||||
new->ifname = strdup(ifname);
|
new->ifname = strdup(ifname);
|
||||||
listnode_add_sort(ripng_offset_list_master, new);
|
listnode_add_sort(ripng->offset_list_master, new);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_offset_list_del(struct ripng_offset_list *offset)
|
void ripng_offset_list_del(struct ripng_offset_list *offset)
|
||||||
{
|
{
|
||||||
listnode_delete(ripng_offset_list_master, offset);
|
listnode_delete(offset->ripng->offset_list_master, offset);
|
||||||
if (OFFSET_LIST_IN_NAME(offset))
|
if (OFFSET_LIST_IN_NAME(offset))
|
||||||
free(OFFSET_LIST_IN_NAME(offset));
|
free(OFFSET_LIST_IN_NAME(offset));
|
||||||
if (OFFSET_LIST_OUT_NAME(offset))
|
if (OFFSET_LIST_OUT_NAME(offset))
|
||||||
@ -64,12 +64,14 @@ void ripng_offset_list_del(struct ripng_offset_list *offset)
|
|||||||
XFREE(MTYPE_RIPNG_OFFSET_LIST, offset);
|
XFREE(MTYPE_RIPNG_OFFSET_LIST, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname)
|
struct ripng_offset_list *ripng_offset_list_lookup(struct ripng *ripng,
|
||||||
|
const char *ifname)
|
||||||
{
|
{
|
||||||
struct ripng_offset_list *offset;
|
struct ripng_offset_list *offset;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) {
|
for (ALL_LIST_ELEMENTS(ripng->offset_list_master, node, nnode,
|
||||||
|
offset)) {
|
||||||
if (strcmp(offset->ifname, ifname) == 0)
|
if (strcmp(offset->ifname, ifname) == 0)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -77,14 +79,14 @@ struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If metric is modifed return 1. */
|
/* If metric is modifed return 1. */
|
||||||
int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
|
int ripng_offset_list_apply_in(struct ripng *ripng, struct prefix_ipv6 *p,
|
||||||
uint8_t *metric)
|
struct interface *ifp, uint8_t *metric)
|
||||||
{
|
{
|
||||||
struct ripng_offset_list *offset;
|
struct ripng_offset_list *offset;
|
||||||
struct access_list *alist;
|
struct access_list *alist;
|
||||||
|
|
||||||
/* Look up offset-list with interface name. */
|
/* Look up offset-list with interface name. */
|
||||||
offset = ripng_offset_list_lookup(ifp->name);
|
offset = ripng_offset_list_lookup(ripng, ifp->name);
|
||||||
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP6,
|
alist = access_list_lookup(AFI_IP6,
|
||||||
OFFSET_LIST_IN_NAME(offset));
|
OFFSET_LIST_IN_NAME(offset));
|
||||||
@ -98,7 +100,7 @@ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Look up offset-list without interface name. */
|
/* Look up offset-list without interface name. */
|
||||||
offset = ripng_offset_list_lookup("*");
|
offset = ripng_offset_list_lookup(ripng, "*");
|
||||||
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
if (offset && OFFSET_LIST_IN_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP6,
|
alist = access_list_lookup(AFI_IP6,
|
||||||
OFFSET_LIST_IN_NAME(offset));
|
OFFSET_LIST_IN_NAME(offset));
|
||||||
@ -115,14 +117,14 @@ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If metric is modifed return 1. */
|
/* If metric is modifed return 1. */
|
||||||
int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
|
int ripng_offset_list_apply_out(struct ripng *ripng, struct prefix_ipv6 *p,
|
||||||
uint8_t *metric)
|
struct interface *ifp, uint8_t *metric)
|
||||||
{
|
{
|
||||||
struct ripng_offset_list *offset;
|
struct ripng_offset_list *offset;
|
||||||
struct access_list *alist;
|
struct access_list *alist;
|
||||||
|
|
||||||
/* Look up offset-list with interface name. */
|
/* Look up offset-list with interface name. */
|
||||||
offset = ripng_offset_list_lookup(ifp->name);
|
offset = ripng_offset_list_lookup(ripng, ifp->name);
|
||||||
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP6,
|
alist = access_list_lookup(AFI_IP6,
|
||||||
OFFSET_LIST_OUT_NAME(offset));
|
OFFSET_LIST_OUT_NAME(offset));
|
||||||
@ -137,7 +139,7 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Look up offset-list without interface name. */
|
/* Look up offset-list without interface name. */
|
||||||
offset = ripng_offset_list_lookup("*");
|
offset = ripng_offset_list_lookup(ripng, "*");
|
||||||
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
if (offset && OFFSET_LIST_OUT_NAME(offset)) {
|
||||||
alist = access_list_lookup(AFI_IP6,
|
alist = access_list_lookup(AFI_IP6,
|
||||||
OFFSET_LIST_OUT_NAME(offset));
|
OFFSET_LIST_OUT_NAME(offset));
|
||||||
@ -153,26 +155,7 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int offset_list_cmp(struct ripng_offset_list *o1,
|
int offset_list_cmp(struct ripng_offset_list *o1, struct ripng_offset_list *o2)
|
||||||
struct ripng_offset_list *o2)
|
|
||||||
{
|
{
|
||||||
return strcmp(o1->ifname, o2->ifname);
|
return strcmp(o1->ifname, o2->ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_offset_init(void)
|
|
||||||
{
|
|
||||||
ripng_offset_list_master = list_new();
|
|
||||||
ripng_offset_list_master->cmp =
|
|
||||||
(int (*)(void *, void *))offset_list_cmp;
|
|
||||||
ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ripng_offset_clean(void)
|
|
||||||
{
|
|
||||||
list_delete(&ripng_offset_list_master);
|
|
||||||
|
|
||||||
ripng_offset_list_master = list_new();
|
|
||||||
ripng_offset_list_master->cmp =
|
|
||||||
(int (*)(void *, void *))offset_list_cmp;
|
|
||||||
ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del;
|
|
||||||
}
|
|
||||||
|
@ -34,10 +34,6 @@
|
|||||||
#include "ripngd/ripngd.h"
|
#include "ripngd/ripngd.h"
|
||||||
#include "ripngd/ripng_nexthop.h"
|
#include "ripngd/ripng_nexthop.h"
|
||||||
|
|
||||||
|
|
||||||
/* Linked list of RIPng peer. */
|
|
||||||
struct list *peer_list;
|
|
||||||
|
|
||||||
static struct ripng_peer *ripng_peer_new(void)
|
static struct ripng_peer *ripng_peer_new(void)
|
||||||
{
|
{
|
||||||
return XCALLOC(MTYPE_RIPNG_PEER, sizeof(struct ripng_peer));
|
return XCALLOC(MTYPE_RIPNG_PEER, sizeof(struct ripng_peer));
|
||||||
@ -45,27 +41,29 @@ static struct ripng_peer *ripng_peer_new(void)
|
|||||||
|
|
||||||
static void ripng_peer_free(struct ripng_peer *peer)
|
static void ripng_peer_free(struct ripng_peer *peer)
|
||||||
{
|
{
|
||||||
|
RIPNG_TIMER_OFF(peer->t_timeout);
|
||||||
XFREE(MTYPE_RIPNG_PEER, peer);
|
XFREE(MTYPE_RIPNG_PEER, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ripng_peer *ripng_peer_lookup(struct in6_addr *addr)
|
struct ripng_peer *ripng_peer_lookup(struct ripng *ripng, struct in6_addr *addr)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
|
||||||
if (IPV6_ADDR_SAME(&peer->addr, addr))
|
if (IPV6_ADDR_SAME(&peer->addr, addr))
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ripng_peer *ripng_peer_lookup_next(struct in6_addr *addr)
|
struct ripng_peer *ripng_peer_lookup_next(struct ripng *ripng,
|
||||||
|
struct in6_addr *addr)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
|
||||||
if (addr6_cmp(&peer->addr, addr) > 0)
|
if (addr6_cmp(&peer->addr, addr) > 0)
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
@ -80,26 +78,28 @@ static int ripng_peer_timeout(struct thread *t)
|
|||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
|
|
||||||
peer = THREAD_ARG(t);
|
peer = THREAD_ARG(t);
|
||||||
listnode_delete(peer_list, peer);
|
listnode_delete(peer->ripng->peer_list, peer);
|
||||||
ripng_peer_free(peer);
|
ripng_peer_free(peer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get RIPng peer. At the same time update timeout thread. */
|
/* Get RIPng peer. At the same time update timeout thread. */
|
||||||
static struct ripng_peer *ripng_peer_get(struct in6_addr *addr)
|
static struct ripng_peer *ripng_peer_get(struct ripng *ripng,
|
||||||
|
struct in6_addr *addr)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
|
|
||||||
peer = ripng_peer_lookup(addr);
|
peer = ripng_peer_lookup(ripng, addr);
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if (peer->t_timeout)
|
if (peer->t_timeout)
|
||||||
thread_cancel(peer->t_timeout);
|
thread_cancel(peer->t_timeout);
|
||||||
} else {
|
} else {
|
||||||
peer = ripng_peer_new();
|
peer = ripng_peer_new();
|
||||||
peer->addr = *addr; /* XXX */
|
peer->ripng = ripng;
|
||||||
listnode_add_sort(peer_list, peer);
|
peer->addr = *addr;
|
||||||
|
listnode_add_sort(ripng->peer_list, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update timeout thread. */
|
/* Update timeout thread. */
|
||||||
@ -113,24 +113,25 @@ static struct ripng_peer *ripng_peer_get(struct in6_addr *addr)
|
|||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_peer_update(struct sockaddr_in6 *from, uint8_t version)
|
void ripng_peer_update(struct ripng *ripng, struct sockaddr_in6 *from,
|
||||||
|
uint8_t version)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
peer = ripng_peer_get(&from->sin6_addr);
|
peer = ripng_peer_get(ripng, &from->sin6_addr);
|
||||||
peer->version = version;
|
peer->version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_peer_bad_route(struct sockaddr_in6 *from)
|
void ripng_peer_bad_route(struct ripng *ripng, struct sockaddr_in6 *from)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
peer = ripng_peer_get(&from->sin6_addr);
|
peer = ripng_peer_get(ripng, &from->sin6_addr);
|
||||||
peer->recv_badroutes++;
|
peer->recv_badroutes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_peer_bad_packet(struct sockaddr_in6 *from)
|
void ripng_peer_bad_packet(struct ripng *ripng, struct sockaddr_in6 *from)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
peer = ripng_peer_get(&from->sin6_addr);
|
peer = ripng_peer_get(ripng, &from->sin6_addr);
|
||||||
peer->recv_badpackets++;
|
peer->recv_badpackets++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,14 +164,14 @@ static char *ripng_peer_uptime(struct ripng_peer *peer, char *buf, size_t len)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_peer_display(struct vty *vty)
|
void ripng_peer_display(struct vty *vty, struct ripng *ripng)
|
||||||
{
|
{
|
||||||
struct ripng_peer *peer;
|
struct ripng_peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
#define RIPNG_UPTIME_LEN 25
|
#define RIPNG_UPTIME_LEN 25
|
||||||
char timebuf[RIPNG_UPTIME_LEN];
|
char timebuf[RIPNG_UPTIME_LEN];
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) {
|
||||||
vty_out(vty, " %s \n%14s %10d %10d %10d %s\n",
|
vty_out(vty, " %s \n%14s %10d %10d %10d %s\n",
|
||||||
inet6_ntoa(peer->addr), " ", peer->recv_badpackets,
|
inet6_ntoa(peer->addr), " ", peer->recv_badpackets,
|
||||||
peer->recv_badroutes, ZEBRA_RIPNG_DISTANCE_DEFAULT,
|
peer->recv_badroutes, ZEBRA_RIPNG_DISTANCE_DEFAULT,
|
||||||
@ -178,13 +179,12 @@ void ripng_peer_display(struct vty *vty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
|
int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
|
||||||
{
|
{
|
||||||
return memcmp(&p1->addr, &p2->addr, sizeof(struct in6_addr));
|
return memcmp(&p1->addr, &p2->addr, sizeof(struct in6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_peer_init(void)
|
void ripng_peer_list_del(void *arg)
|
||||||
{
|
{
|
||||||
peer_list = list_new();
|
ripng_peer_free(arg);
|
||||||
peer_list->cmp = (int (*)(void *, void *))ripng_peer_list_cmp;
|
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ void ripng_aggregate_decrement_list(struct agg_node *child, struct list *list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RIPng routes treatment. */
|
/* RIPng routes treatment. */
|
||||||
int ripng_aggregate_add(struct prefix *p)
|
int ripng_aggregate_add(struct ripng *ripng, struct prefix *p)
|
||||||
{
|
{
|
||||||
struct agg_node *top;
|
struct agg_node *top;
|
||||||
struct agg_node *rp;
|
struct agg_node *rp;
|
||||||
@ -124,7 +124,7 @@ int ripng_aggregate_add(struct prefix *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Delete RIPng static route. */
|
/* Delete RIPng static route. */
|
||||||
int ripng_aggregate_delete(struct prefix *p)
|
int ripng_aggregate_delete(struct ripng *ripng, struct prefix *p)
|
||||||
{
|
{
|
||||||
struct agg_node *top;
|
struct agg_node *top;
|
||||||
struct agg_node *rp;
|
struct agg_node *rp;
|
||||||
|
@ -48,8 +48,8 @@ extern void ripng_aggregate_decrement(struct agg_node *rp,
|
|||||||
struct ripng_info *rinfo);
|
struct ripng_info *rinfo);
|
||||||
extern void ripng_aggregate_decrement_list(struct agg_node *rp,
|
extern void ripng_aggregate_decrement_list(struct agg_node *rp,
|
||||||
struct list *list);
|
struct list *list);
|
||||||
extern int ripng_aggregate_add(struct prefix *p);
|
extern int ripng_aggregate_add(struct ripng *ripng, struct prefix *p);
|
||||||
extern int ripng_aggregate_delete(struct prefix *p);
|
extern int ripng_aggregate_delete(struct ripng *ripng, struct prefix *p);
|
||||||
extern void ripng_aggregate_free(struct ripng_aggregate *aggregate);
|
extern void ripng_aggregate_free(struct ripng_aggregate *aggregate);
|
||||||
|
|
||||||
#endif /* _ZEBRA_RIPNG_ROUTE_H */
|
#endif /* _ZEBRA_RIPNG_ROUTE_H */
|
||||||
|
@ -37,7 +37,8 @@
|
|||||||
struct zclient *zclient = NULL;
|
struct zclient *zclient = NULL;
|
||||||
|
|
||||||
/* Send ECMP routes to zebra. */
|
/* Send ECMP routes to zebra. */
|
||||||
static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd)
|
static void ripng_zebra_ipv6_send(struct ripng *ripng, struct agg_node *rp,
|
||||||
|
uint8_t cmd)
|
||||||
{
|
{
|
||||||
struct list *list = (struct list *)rp->info;
|
struct list *list = (struct list *)rp->info;
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
@ -47,7 +48,7 @@ static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = VRF_DEFAULT;
|
api.vrf_id = ripng->vrf->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_RIPNG;
|
api.type = ZEBRA_ROUTE_RIPNG;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
api.prefix = rp->p;
|
api.prefix = rp->p;
|
||||||
@ -57,7 +58,7 @@ static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd)
|
|||||||
if (count >= MULTIPATH_NUM)
|
if (count >= MULTIPATH_NUM)
|
||||||
break;
|
break;
|
||||||
api_nh = &api.nexthops[count];
|
api_nh = &api.nexthops[count];
|
||||||
api_nh->vrf_id = VRF_DEFAULT;
|
api_nh->vrf_id = ripng->vrf->vrf_id;
|
||||||
api_nh->gate.ipv6 = rinfo->nexthop;
|
api_nh->gate.ipv6 = rinfo->nexthop;
|
||||||
api_nh->ifindex = rinfo->ifindex;
|
api_nh->ifindex = rinfo->ifindex;
|
||||||
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
@ -100,25 +101,30 @@ static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add/update ECMP routes to zebra. */
|
/* Add/update ECMP routes to zebra. */
|
||||||
void ripng_zebra_ipv6_add(struct agg_node *rp)
|
void ripng_zebra_ipv6_add(struct ripng *ripng, struct agg_node *rp)
|
||||||
{
|
{
|
||||||
ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_ADD);
|
ripng_zebra_ipv6_send(ripng, rp, ZEBRA_ROUTE_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete ECMP routes from zebra. */
|
/* Delete ECMP routes from zebra. */
|
||||||
void ripng_zebra_ipv6_delete(struct agg_node *rp)
|
void ripng_zebra_ipv6_delete(struct ripng *ripng, struct agg_node *rp)
|
||||||
{
|
{
|
||||||
ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_DELETE);
|
ripng_zebra_ipv6_send(ripng, rp, ZEBRA_ROUTE_DELETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zebra route add and delete treatment. */
|
/* Zebra route add and delete treatment. */
|
||||||
static int ripng_zebra_read_route(int command, struct zclient *zclient,
|
static int ripng_zebra_read_route(int command, struct zclient *zclient,
|
||||||
zebra_size_t length, vrf_id_t vrf_id)
|
zebra_size_t length, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
|
struct ripng *ripng;
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
struct in6_addr nexthop;
|
struct in6_addr nexthop;
|
||||||
unsigned long ifindex;
|
unsigned long ifindex;
|
||||||
|
|
||||||
|
ripng = ripng_lookup_by_vrf_id(vrf_id);
|
||||||
|
if (!ripng)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (zapi_route_decode(zclient->ibuf, &api) < 0)
|
if (zapi_route_decode(zclient->ibuf, &api) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -133,69 +139,97 @@ static int ripng_zebra_read_route(int command, struct zclient *zclient,
|
|||||||
ifindex = api.nexthops[0].ifindex;
|
ifindex = api.nexthops[0].ifindex;
|
||||||
|
|
||||||
if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
||||||
ripng_redistribute_add(api.type, RIPNG_ROUTE_REDISTRIBUTE,
|
ripng_redistribute_add(ripng, api.type,
|
||||||
|
RIPNG_ROUTE_REDISTRIBUTE,
|
||||||
(struct prefix_ipv6 *)&api.prefix,
|
(struct prefix_ipv6 *)&api.prefix,
|
||||||
ifindex, &nexthop, api.tag);
|
ifindex, &nexthop, api.tag);
|
||||||
else
|
else
|
||||||
ripng_redistribute_delete(api.type, RIPNG_ROUTE_REDISTRIBUTE,
|
ripng_redistribute_delete(
|
||||||
(struct prefix_ipv6 *)&api.prefix,
|
ripng, api.type, RIPNG_ROUTE_REDISTRIBUTE,
|
||||||
ifindex);
|
(struct prefix_ipv6 *)&api.prefix, ifindex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_redistribute_conf_update(int type)
|
void ripng_redistribute_conf_update(struct ripng *ripng, int type)
|
||||||
{
|
{
|
||||||
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
|
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
|
||||||
VRF_DEFAULT);
|
ripng->vrf->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_redistribute_conf_delete(int type)
|
void ripng_redistribute_conf_delete(struct ripng *ripng, int type)
|
||||||
{
|
{
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
|
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
|
||||||
AFI_IP6, type, 0, VRF_DEFAULT);
|
AFI_IP6, type, 0, ripng->vrf->vrf_id);
|
||||||
|
|
||||||
ripng_redistribute_withdraw(type);
|
ripng_redistribute_withdraw(ripng, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ripng_redistribute_check(int type)
|
int ripng_redistribute_check(struct ripng *ripng, int type)
|
||||||
{
|
{
|
||||||
return vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT);
|
return ripng->redist[type].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_redistribute_clean(void)
|
void ripng_redistribute_enable(struct ripng *ripng)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
if (!vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT))
|
if (!ripng_redistribute_check(ripng, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (zclient->sock > 0)
|
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
|
||||||
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE,
|
AFI_IP6, i, 0, ripng->vrf->vrf_id);
|
||||||
zclient, AFI_IP6, i, 0,
|
|
||||||
VRF_DEFAULT);
|
|
||||||
|
|
||||||
vrf_bitmap_unset(zclient->redist[AFI_IP6][i], VRF_DEFAULT);
|
|
||||||
|
|
||||||
/* Remove the routes from RIP table. */
|
|
||||||
ripng_redistribute_withdraw(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ripng_redistribute_write(struct vty *vty)
|
void ripng_redistribute_disable(struct ripng *ripng)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
|
if (!ripng_redistribute_check(ripng, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
|
||||||
|
AFI_IP6, i, 0, ripng->vrf->vrf_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ripng_redistribute_write(struct vty *vty, struct ripng *ripng)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
if (i == zclient->redist_default
|
if (i == zclient->redist_default
|
||||||
|| !vrf_bitmap_check(zclient->redist[AFI_IP6][i],
|
|| !ripng_redistribute_check(ripng, i))
|
||||||
VRF_DEFAULT))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vty_out(vty, " %s", zebra_route_string(i));
|
vty_out(vty, " %s", zebra_route_string(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ripng_zebra_vrf_register(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
if (vrf->vrf_id == VRF_DEFAULT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IS_RIPNG_DEBUG_EVENT)
|
||||||
|
zlog_debug("%s: register VRF %s(%u) to zebra", __func__,
|
||||||
|
vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
|
zclient_send_reg_requests(zclient, vrf->vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ripng_zebra_vrf_deregister(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
if (vrf->vrf_id == VRF_DEFAULT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IS_RIPNG_DEBUG_EVENT)
|
||||||
|
zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__,
|
||||||
|
vrf->name, vrf->vrf_id);
|
||||||
|
|
||||||
|
zclient_send_dereg_requests(zclient, vrf->vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
static void ripng_zebra_connected(struct zclient *zclient)
|
static void ripng_zebra_connected(struct zclient *zclient)
|
||||||
{
|
{
|
||||||
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
||||||
@ -215,6 +249,7 @@ void zebra_init(struct thread_master *master)
|
|||||||
zclient->interface_delete = ripng_interface_delete;
|
zclient->interface_delete = ripng_interface_delete;
|
||||||
zclient->interface_address_add = ripng_interface_address_add;
|
zclient->interface_address_add = ripng_interface_address_add;
|
||||||
zclient->interface_address_delete = ripng_interface_address_delete;
|
zclient->interface_address_delete = ripng_interface_address_delete;
|
||||||
|
zclient->interface_vrf_update = ripng_interface_vrf_update;
|
||||||
zclient->redistribute_route_add = ripng_zebra_read_route;
|
zclient->redistribute_route_add = ripng_zebra_read_route;
|
||||||
zclient->redistribute_route_del = ripng_zebra_read_route;
|
zclient->redistribute_route_del = ripng_zebra_read_route;
|
||||||
}
|
}
|
||||||
|
721
ripngd/ripngd.c
721
ripngd/ripngd.c
File diff suppressed because it is too large
Load Diff
172
ripngd/ripngd.h
172
ripngd/ripngd.h
@ -25,6 +25,7 @@
|
|||||||
#include <zclient.h>
|
#include <zclient.h>
|
||||||
#include <vty.h>
|
#include <vty.h>
|
||||||
#include <distribute.h>
|
#include <distribute.h>
|
||||||
|
#include <vector.h>
|
||||||
|
|
||||||
#include "ripng_memory.h"
|
#include "ripng_memory.h"
|
||||||
|
|
||||||
@ -88,6 +89,17 @@
|
|||||||
|
|
||||||
/* RIPng structure. */
|
/* RIPng structure. */
|
||||||
struct ripng {
|
struct ripng {
|
||||||
|
RB_ENTRY(ripng) entry;
|
||||||
|
|
||||||
|
/* VRF this routing instance is associated with. */
|
||||||
|
char *vrf_name;
|
||||||
|
|
||||||
|
/* VRF backpointer (might be NULL if the VRF doesn't exist). */
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
/* Status of the routing instance. */
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
/* RIPng socket. */
|
/* RIPng socket. */
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
@ -107,6 +119,21 @@ struct ripng {
|
|||||||
/* RIPng routing information base. */
|
/* RIPng routing information base. */
|
||||||
struct agg_table *table;
|
struct agg_table *table;
|
||||||
|
|
||||||
|
/* Linked list of RIPng peers. */
|
||||||
|
struct list *peer_list;
|
||||||
|
|
||||||
|
/* RIPng enabled interfaces. */
|
||||||
|
vector enable_if;
|
||||||
|
|
||||||
|
/* RIPng enabled networks. */
|
||||||
|
struct agg_table *enable_network;
|
||||||
|
|
||||||
|
/* Vector to store passive-interface name. */
|
||||||
|
vector passive_interface;
|
||||||
|
|
||||||
|
/* RIPng offset-lists. */
|
||||||
|
struct list *offset_list_master;
|
||||||
|
|
||||||
/* RIPng threads. */
|
/* RIPng threads. */
|
||||||
struct thread *t_read;
|
struct thread *t_read;
|
||||||
struct thread *t_write;
|
struct thread *t_write;
|
||||||
@ -122,13 +149,16 @@ struct ripng {
|
|||||||
/* RIPng ECMP flag */
|
/* RIPng ECMP flag */
|
||||||
bool ecmp;
|
bool ecmp;
|
||||||
|
|
||||||
/* For redistribute route map. */
|
/* RIPng redistribute configuration. */
|
||||||
struct {
|
struct {
|
||||||
char *name;
|
bool enabled;
|
||||||
struct route_map *map;
|
struct {
|
||||||
|
char *name;
|
||||||
|
struct route_map *map;
|
||||||
|
} route_map;
|
||||||
bool metric_config;
|
bool metric_config;
|
||||||
uint8_t metric;
|
uint8_t metric;
|
||||||
} route_map[ZEBRA_ROUTE_MAX];
|
} redist[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
/* For distribute-list container */
|
/* For distribute-list container */
|
||||||
struct distribute_ctx *distribute_ctx;
|
struct distribute_ctx *distribute_ctx;
|
||||||
@ -136,6 +166,8 @@ struct ripng {
|
|||||||
/* For if_rmap container */
|
/* For if_rmap container */
|
||||||
struct if_rmap_ctx *if_rmap_ctx;
|
struct if_rmap_ctx *if_rmap_ctx;
|
||||||
};
|
};
|
||||||
|
RB_HEAD(ripng_instance_head, ripng);
|
||||||
|
RB_PROTOTYPE(ripng_instance_head, ripng, entry, ripng_instance_compare)
|
||||||
|
|
||||||
/* Routing table entry. */
|
/* Routing table entry. */
|
||||||
struct rte {
|
struct rte {
|
||||||
@ -234,6 +266,9 @@ typedef enum {
|
|||||||
|
|
||||||
/* RIPng specific interface configuration. */
|
/* RIPng specific interface configuration. */
|
||||||
struct ripng_interface {
|
struct ripng_interface {
|
||||||
|
/* Parent routing instance. */
|
||||||
|
struct ripng *ripng;
|
||||||
|
|
||||||
/* RIPng is enabled on this interface. */
|
/* RIPng is enabled on this interface. */
|
||||||
int enable_network;
|
int enable_network;
|
||||||
int enable_interface;
|
int enable_interface;
|
||||||
@ -280,6 +315,9 @@ struct ripng_interface {
|
|||||||
|
|
||||||
/* RIPng peer information. */
|
/* RIPng peer information. */
|
||||||
struct ripng_peer {
|
struct ripng_peer {
|
||||||
|
/* Parent routing instance. */
|
||||||
|
struct ripng *ripng;
|
||||||
|
|
||||||
/* Peer address. */
|
/* Peer address. */
|
||||||
struct in6_addr addr;
|
struct in6_addr addr;
|
||||||
|
|
||||||
@ -325,6 +363,9 @@ enum ripng_event {
|
|||||||
#define RIPNG_OFFSET_LIST_MAX 2
|
#define RIPNG_OFFSET_LIST_MAX 2
|
||||||
|
|
||||||
struct ripng_offset_list {
|
struct ripng_offset_list {
|
||||||
|
/* Parent routing instance. */
|
||||||
|
struct ripng *ripng;
|
||||||
|
|
||||||
char *ifname;
|
char *ifname;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -335,72 +376,87 @@ struct ripng_offset_list {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Extern variables. */
|
/* Extern variables. */
|
||||||
extern struct ripng *ripng;
|
|
||||||
extern struct list *peer_list;
|
|
||||||
extern struct zebra_privs_t ripngd_privs;
|
extern struct zebra_privs_t ripngd_privs;
|
||||||
extern struct thread_master *master;
|
extern struct thread_master *master;
|
||||||
|
extern struct ripng_instance_head ripng_instances;
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
extern void ripng_init(void);
|
extern void ripng_init(void);
|
||||||
extern void ripng_clean(void);
|
extern void ripng_clean(struct ripng *ripng);
|
||||||
extern void ripng_clean_network(void);
|
extern void ripng_clean_network(struct ripng *ripng);
|
||||||
extern void ripng_interface_clean(void);
|
extern void ripng_interface_clean(struct ripng *ripng);
|
||||||
extern int ripng_enable_network_add(struct prefix *p);
|
extern int ripng_enable_network_add(struct ripng *ripng, struct prefix *p);
|
||||||
extern int ripng_enable_network_delete(struct prefix *p);
|
extern int ripng_enable_network_delete(struct ripng *ripng, struct prefix *p);
|
||||||
extern int ripng_enable_if_add(const char *ifname);
|
extern int ripng_enable_if_add(struct ripng *ripng, const char *ifname);
|
||||||
extern int ripng_enable_if_delete(const char *ifname);
|
extern int ripng_enable_if_delete(struct ripng *ripng, const char *ifname);
|
||||||
extern int ripng_passive_interface_set(const char *ifname);
|
extern int ripng_passive_interface_set(struct ripng *ripng, const char *ifname);
|
||||||
extern int ripng_passive_interface_unset(const char *ifname);
|
extern int ripng_passive_interface_unset(struct ripng *ripng,
|
||||||
extern void ripng_passive_interface_clean(void);
|
const char *ifname);
|
||||||
|
extern void ripng_passive_interface_clean(struct ripng *ripng);
|
||||||
extern void ripng_if_init(void);
|
extern void ripng_if_init(void);
|
||||||
extern void ripng_route_map_init(void);
|
extern void ripng_route_map_init(void);
|
||||||
|
extern void ripng_zebra_vrf_register(struct vrf *vrf);
|
||||||
|
extern void ripng_zebra_vrf_deregister(struct vrf *vrf);
|
||||||
extern void ripng_terminate(void);
|
extern void ripng_terminate(void);
|
||||||
/* zclient_init() is done by ripng_zebra.c:zebra_init() */
|
/* zclient_init() is done by ripng_zebra.c:zebra_init() */
|
||||||
extern void zebra_init(struct thread_master *);
|
extern void zebra_init(struct thread_master *);
|
||||||
extern void ripng_zebra_stop(void);
|
extern void ripng_zebra_stop(void);
|
||||||
extern void ripng_redistribute_conf_update(int type);
|
extern void ripng_redistribute_conf_update(struct ripng *ripng, int type);
|
||||||
extern void ripng_redistribute_conf_delete(int type);
|
extern void ripng_redistribute_conf_delete(struct ripng *ripng, int type);
|
||||||
|
|
||||||
extern void ripng_peer_init(void);
|
extern void ripng_peer_update(struct ripng *ripng, struct sockaddr_in6 *from,
|
||||||
extern void ripng_peer_update(struct sockaddr_in6 *, uint8_t);
|
uint8_t version);
|
||||||
extern void ripng_peer_bad_route(struct sockaddr_in6 *);
|
extern void ripng_peer_bad_route(struct ripng *ripng,
|
||||||
extern void ripng_peer_bad_packet(struct sockaddr_in6 *);
|
struct sockaddr_in6 *from);
|
||||||
extern void ripng_peer_display(struct vty *);
|
extern void ripng_peer_bad_packet(struct ripng *ripng,
|
||||||
extern struct ripng_peer *ripng_peer_lookup(struct in6_addr *);
|
struct sockaddr_in6 *from);
|
||||||
extern struct ripng_peer *ripng_peer_lookup_next(struct in6_addr *);
|
extern void ripng_peer_display(struct vty *vty, struct ripng *ripng);
|
||||||
|
extern struct ripng_peer *ripng_peer_lookup(struct ripng *ripng,
|
||||||
|
struct in6_addr *addr);
|
||||||
|
extern struct ripng_peer *ripng_peer_lookup_next(struct ripng *ripng,
|
||||||
|
struct in6_addr *addr);
|
||||||
|
extern int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2);
|
||||||
|
extern void ripng_peer_list_del(void *arg);
|
||||||
|
|
||||||
extern struct ripng_offset_list *ripng_offset_list_new(const char *ifname);
|
extern struct ripng_offset_list *ripng_offset_list_new(struct ripng *ripng,
|
||||||
|
const char *ifname);
|
||||||
extern void ripng_offset_list_del(struct ripng_offset_list *offset);
|
extern void ripng_offset_list_del(struct ripng_offset_list *offset);
|
||||||
extern struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname);
|
extern struct ripng_offset_list *ripng_offset_list_lookup(struct ripng *ripng,
|
||||||
extern struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname);
|
const char *ifname);
|
||||||
extern int ripng_offset_list_apply_in(struct prefix_ipv6 *, struct interface *,
|
extern int ripng_offset_list_apply_in(struct ripng *ripng,
|
||||||
uint8_t *);
|
struct prefix_ipv6 *p,
|
||||||
extern int ripng_offset_list_apply_out(struct prefix_ipv6 *, struct interface *,
|
struct interface *ifp, uint8_t *metric);
|
||||||
uint8_t *);
|
extern int ripng_offset_list_apply_out(struct ripng *ripng,
|
||||||
extern void ripng_offset_init(void);
|
struct prefix_ipv6 *p,
|
||||||
extern void ripng_offset_clean(void);
|
struct interface *ifp, uint8_t *metric);
|
||||||
|
extern int offset_list_cmp(struct ripng_offset_list *o1,
|
||||||
|
struct ripng_offset_list *o2);
|
||||||
|
|
||||||
extern int ripng_route_rte(struct ripng_info *rinfo);
|
extern int ripng_route_rte(struct ripng_info *rinfo);
|
||||||
extern struct ripng_info *ripng_info_new(void);
|
extern struct ripng_info *ripng_info_new(void);
|
||||||
extern void ripng_info_free(struct ripng_info *rinfo);
|
extern void ripng_info_free(struct ripng_info *rinfo);
|
||||||
extern void ripng_event(enum ripng_event, int);
|
extern struct ripng *ripng_info_get_instance(const struct ripng_info *rinfo);
|
||||||
|
extern void ripng_event(struct ripng *ripng, enum ripng_event event, int sock);
|
||||||
extern int ripng_request(struct interface *ifp);
|
extern int ripng_request(struct interface *ifp);
|
||||||
extern void ripng_redistribute_add(int, int, struct prefix_ipv6 *, ifindex_t,
|
extern void ripng_redistribute_add(struct ripng *ripng, int type, int sub_type,
|
||||||
struct in6_addr *, route_tag_t);
|
struct prefix_ipv6 *p, ifindex_t ifindex,
|
||||||
extern void ripng_redistribute_delete(int, int, struct prefix_ipv6 *,
|
struct in6_addr *nexthop, route_tag_t tag);
|
||||||
ifindex_t);
|
extern void ripng_redistribute_delete(struct ripng *ripng, int type,
|
||||||
extern void ripng_redistribute_withdraw(int type);
|
int sub_type, struct prefix_ipv6 *p,
|
||||||
|
ifindex_t ifindex);
|
||||||
|
extern void ripng_redistribute_withdraw(struct ripng *ripng, int type);
|
||||||
|
|
||||||
extern void ripng_ecmp_disable(void);
|
extern void ripng_ecmp_disable(struct ripng *ripng);
|
||||||
extern void ripng_distribute_update_interface(struct interface *);
|
extern void ripng_distribute_update_interface(struct interface *);
|
||||||
extern void ripng_if_rmap_update_interface(struct interface *);
|
extern void ripng_if_rmap_update_interface(struct interface *);
|
||||||
|
|
||||||
extern void ripng_zebra_ipv6_add(struct agg_node *node);
|
extern void ripng_zebra_ipv6_add(struct ripng *ripng, struct agg_node *node);
|
||||||
extern void ripng_zebra_ipv6_delete(struct agg_node *node);
|
extern void ripng_zebra_ipv6_delete(struct ripng *ripng, struct agg_node *node);
|
||||||
|
|
||||||
extern void ripng_redistribute_clean(void);
|
extern void ripng_redistribute_enable(struct ripng *ripng);
|
||||||
extern int ripng_redistribute_check(int);
|
extern void ripng_redistribute_disable(struct ripng *ripng);
|
||||||
extern void ripng_redistribute_write(struct vty *);
|
extern int ripng_redistribute_check(struct ripng *ripng, int type);
|
||||||
|
extern void ripng_redistribute_write(struct vty *vty, struct ripng *ripng);
|
||||||
|
|
||||||
extern int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p,
|
extern int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *nexthop, uint16_t tag,
|
struct in6_addr *nexthop, uint16_t tag,
|
||||||
@ -423,14 +479,26 @@ extern int ripng_interface_address_add(int command, struct zclient *,
|
|||||||
zebra_size_t, vrf_id_t);
|
zebra_size_t, vrf_id_t);
|
||||||
extern int ripng_interface_address_delete(int command, struct zclient *,
|
extern int ripng_interface_address_delete(int command, struct zclient *,
|
||||||
zebra_size_t, vrf_id_t);
|
zebra_size_t, vrf_id_t);
|
||||||
|
extern int ripng_interface_vrf_update(int command, struct zclient *zclient,
|
||||||
|
zebra_size_t length, vrf_id_t vrf_id);
|
||||||
|
extern void ripng_interface_sync(struct interface *ifp);
|
||||||
|
|
||||||
extern int ripng_create(int socket);
|
extern struct ripng *ripng_lookup_by_vrf_id(vrf_id_t vrf_id);
|
||||||
extern int ripng_make_socket(void);
|
extern struct ripng *ripng_lookup_by_vrf_name(const char *vrf_name);
|
||||||
extern int ripng_network_write(struct vty *);
|
extern struct ripng *ripng_create(const char *vrf_name, struct vrf *vrf,
|
||||||
|
int socket);
|
||||||
|
extern int ripng_make_socket(struct vrf *vrf);
|
||||||
|
extern int ripng_network_write(struct vty *vty, struct ripng *ripng);
|
||||||
|
|
||||||
extern struct ripng_info *ripng_ecmp_add(struct ripng_info *);
|
extern struct ripng_info *ripng_ecmp_add(struct ripng *ripng,
|
||||||
extern struct ripng_info *ripng_ecmp_replace(struct ripng_info *);
|
struct ripng_info *rinfo);
|
||||||
extern struct ripng_info *ripng_ecmp_delete(struct ripng_info *);
|
extern struct ripng_info *ripng_ecmp_replace(struct ripng *ripng,
|
||||||
|
struct ripng_info *rinfo);
|
||||||
|
extern struct ripng_info *ripng_ecmp_delete(struct ripng *ripng,
|
||||||
|
struct ripng_info *rinfo);
|
||||||
|
|
||||||
|
extern void ripng_vrf_init(void);
|
||||||
|
extern void ripng_vrf_terminate(void);
|
||||||
|
|
||||||
/* Northbound. */
|
/* Northbound. */
|
||||||
extern void ripng_cli_init(void);
|
extern void ripng_cli_init(void);
|
||||||
|
@ -1521,15 +1521,15 @@ DEFUNSH(VTYSH_KEYS, key, key_cmd, "key (0-2147483647)",
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUNSH(VTYSH_RIPD, router_rip, router_rip_cmd, "router rip",
|
DEFUNSH(VTYSH_RIPD, router_rip, router_rip_cmd, "router rip [vrf NAME]",
|
||||||
ROUTER_STR "RIP\n")
|
ROUTER_STR "RIP\n" VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
vty->node = RIP_NODE;
|
vty->node = RIP_NODE;
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng",
|
DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng [vrf NAME]",
|
||||||
ROUTER_STR "RIPng\n")
|
ROUTER_STR "RIPng\n" VRF_CMD_HELP_STR)
|
||||||
{
|
{
|
||||||
vty->node = RIPNG_NODE;
|
vty->node = RIPNG_NODE;
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -20,25 +20,28 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"frr-ripd:ripd": {
|
"frr-ripd:ripd": {
|
||||||
"instance": {
|
"instance": [
|
||||||
"allow-ecmp": "true",
|
{
|
||||||
"distance": {
|
"vrf": "default",
|
||||||
"source": [
|
"allow-ecmp": "true",
|
||||||
|
"distance": {
|
||||||
|
"source": [
|
||||||
|
{
|
||||||
|
"distance": "25",
|
||||||
|
"prefix": "172.16.1.0/24"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"redistribute": [
|
||||||
{
|
{
|
||||||
"prefix": "172.16.1.0/24",
|
"metric": "3",
|
||||||
"distance": "25"
|
"protocol": "ospf"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"static-route": [
|
||||||
|
"10.0.1.0/24"
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"redistribute": [
|
]
|
||||||
{
|
|
||||||
"protocol": "ospf",
|
|
||||||
"metric": "3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"static-route": [
|
|
||||||
"10.0.1.0/24"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
</lib>
|
</lib>
|
||||||
<ripd xmlns="http://frrouting.org/yang/ripd">
|
<ripd xmlns="http://frrouting.org/yang/ripd">
|
||||||
<instance>
|
<instance>
|
||||||
|
<vrf>default</vrf>
|
||||||
<allow-ecmp>true</allow-ecmp>
|
<allow-ecmp>true</allow-ecmp>
|
||||||
<static-route>10.0.1.0/24</static-route>
|
<static-route>10.0.1.0/24</static-route>
|
||||||
<distance>
|
<distance>
|
||||||
|
@ -34,13 +34,18 @@ module frr-ripd {
|
|||||||
|
|
||||||
container ripd {
|
container ripd {
|
||||||
/*
|
/*
|
||||||
* Global configuration data
|
* Routing instance configuration.
|
||||||
*/
|
*/
|
||||||
container instance {
|
list instance {
|
||||||
presence "Present if the RIP protocol is enabled.";
|
key "vrf";
|
||||||
description
|
description
|
||||||
"RIP routing instance.";
|
"RIP routing instance.";
|
||||||
|
|
||||||
|
leaf vrf {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"VRF name.";
|
||||||
|
}
|
||||||
leaf allow-ecmp {
|
leaf allow-ecmp {
|
||||||
type boolean;
|
type boolean;
|
||||||
default "false";
|
default "false";
|
||||||
@ -293,83 +298,83 @@ module frr-ripd {
|
|||||||
'(./receive = "2" and ./send = "2") or ' +
|
'(./receive = "2" and ./send = "2") or ' +
|
||||||
'(./receive = "1-2" and ./send = "2")';
|
'(./receive = "1-2" and ./send = "2")';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Operational data.
|
* Operational data.
|
||||||
*/
|
*/
|
||||||
container state {
|
container state {
|
||||||
config false;
|
config false;
|
||||||
description
|
|
||||||
"Operational data.";
|
|
||||||
|
|
||||||
container neighbors {
|
|
||||||
description
|
description
|
||||||
"Neighbor information.";
|
"Operational data.";
|
||||||
list neighbor {
|
|
||||||
key "address";
|
container neighbors {
|
||||||
description
|
description
|
||||||
"A RIP neighbor.";
|
"Neighbor information.";
|
||||||
leaf address {
|
list neighbor {
|
||||||
type inet:ipv4-address;
|
key "address";
|
||||||
description
|
description
|
||||||
"IP address that a RIP neighbor is using as its
|
"A RIP neighbor.";
|
||||||
source address.";
|
leaf address {
|
||||||
}
|
type inet:ipv4-address;
|
||||||
leaf last-update {
|
description
|
||||||
type yang:date-and-time;
|
"IP address that a RIP neighbor is using as its
|
||||||
description
|
source address.";
|
||||||
"The time when the most recent RIP update was
|
}
|
||||||
received from this neighbor.";
|
leaf last-update {
|
||||||
}
|
type yang:date-and-time;
|
||||||
leaf bad-packets-rcvd {
|
description
|
||||||
type yang:counter32;
|
"The time when the most recent RIP update was
|
||||||
description
|
received from this neighbor.";
|
||||||
"The number of RIP invalid packets received from
|
}
|
||||||
this neighbor which were subsequently discarded
|
leaf bad-packets-rcvd {
|
||||||
for any reason (e.g. a version 0 packet, or an
|
type yang:counter32;
|
||||||
unknown command type).";
|
description
|
||||||
}
|
"The number of RIP invalid packets received from
|
||||||
leaf bad-routes-rcvd {
|
this neighbor which were subsequently discarded
|
||||||
type yang:counter32;
|
for any reason (e.g. a version 0 packet, or an
|
||||||
description
|
unknown command type).";
|
||||||
"The number of routes received from this neighbor,
|
}
|
||||||
in valid RIP packets, which were ignored for any
|
leaf bad-routes-rcvd {
|
||||||
reason (e.g. unknown address family, or invalid
|
type yang:counter32;
|
||||||
metric).";
|
description
|
||||||
|
"The number of routes received from this neighbor,
|
||||||
|
in valid RIP packets, which were ignored for any
|
||||||
|
reason (e.g. unknown address family, or invalid
|
||||||
|
metric).";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
container routes {
|
||||||
container routes {
|
|
||||||
description
|
|
||||||
"Route information.";
|
|
||||||
list route {
|
|
||||||
key "prefix";
|
|
||||||
description
|
description
|
||||||
"A RIP IPv4 route.";
|
"Route information.";
|
||||||
leaf prefix {
|
list route {
|
||||||
type inet:ipv4-prefix;
|
key "prefix";
|
||||||
description
|
description
|
||||||
"IP address (in the form A.B.C.D) and prefix length,
|
"A RIP IPv4 route.";
|
||||||
separated by the slash (/) character. The range of
|
leaf prefix {
|
||||||
values for the prefix-length is 0 to 32.";
|
type inet:ipv4-prefix;
|
||||||
}
|
description
|
||||||
leaf next-hop {
|
"IP address (in the form A.B.C.D) and prefix length,
|
||||||
type inet:ipv4-address;
|
separated by the slash (/) character. The range of
|
||||||
description
|
values for the prefix-length is 0 to 32.";
|
||||||
"Next hop IPv4 address.";
|
}
|
||||||
}
|
leaf next-hop {
|
||||||
leaf interface {
|
type inet:ipv4-address;
|
||||||
type string;
|
description
|
||||||
description
|
"Next hop IPv4 address.";
|
||||||
"The interface that the route uses.";
|
}
|
||||||
}
|
leaf interface {
|
||||||
leaf metric {
|
type string;
|
||||||
type uint8 {
|
description
|
||||||
range "0..16";
|
"The interface that the route uses.";
|
||||||
|
}
|
||||||
|
leaf metric {
|
||||||
|
type uint8 {
|
||||||
|
range "0..16";
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"Route metric.";
|
||||||
}
|
}
|
||||||
description
|
|
||||||
"Route metric.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,6 +552,19 @@ module frr-ripd {
|
|||||||
description
|
description
|
||||||
"Clears RIP routes from the IP routing table and routes
|
"Clears RIP routes from the IP routing table and routes
|
||||||
redistributed into the RIP protocol.";
|
redistributed into the RIP protocol.";
|
||||||
|
|
||||||
|
input {
|
||||||
|
leaf vrf {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"VRF name identifying a specific RIP instance.
|
||||||
|
This leaf is optional for the rpc.
|
||||||
|
If it is specified, the rpc will clear all routes in the
|
||||||
|
specified RIP instance;
|
||||||
|
if it is not specified, the rpc will clear all routes in
|
||||||
|
all RIP instances.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,13 +33,18 @@ module frr-ripngd {
|
|||||||
|
|
||||||
container ripngd {
|
container ripngd {
|
||||||
/*
|
/*
|
||||||
* Global configuration data
|
* Routing instance configuration.
|
||||||
*/
|
*/
|
||||||
container instance {
|
list instance {
|
||||||
presence "Present if the RIPng protocol is enabled.";
|
key "vrf";
|
||||||
description
|
description
|
||||||
"RIPng routing instance.";
|
"RIPng routing instance.";
|
||||||
|
|
||||||
|
leaf vrf {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"VRF name.";
|
||||||
|
}
|
||||||
leaf allow-ecmp {
|
leaf allow-ecmp {
|
||||||
type boolean;
|
type boolean;
|
||||||
default "false";
|
default "false";
|
||||||
@ -194,82 +199,82 @@ module frr-ripngd {
|
|||||||
"Interval at which RIPng updates are sent.";
|
"Interval at which RIPng updates are sent.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Operational data.
|
* Operational data.
|
||||||
*/
|
*/
|
||||||
container state {
|
container state {
|
||||||
config false;
|
config false;
|
||||||
description
|
|
||||||
"Operational data.";
|
|
||||||
|
|
||||||
container neighbors {
|
|
||||||
description
|
description
|
||||||
"Neighbor information.";
|
"Operational data.";
|
||||||
list neighbor {
|
|
||||||
key "address";
|
container neighbors {
|
||||||
description
|
description
|
||||||
"A RIPng neighbor.";
|
"Neighbor information.";
|
||||||
leaf address {
|
list neighbor {
|
||||||
type inet:ipv6-address;
|
key "address";
|
||||||
description
|
description
|
||||||
"IPv6 address that a RIPng neighbor is using as its
|
"A RIPng neighbor.";
|
||||||
source address.";
|
leaf address {
|
||||||
}
|
type inet:ipv6-address;
|
||||||
leaf last-update {
|
description
|
||||||
type yang:date-and-time;
|
"IPv6 address that a RIPng neighbor is using as its
|
||||||
description
|
source address.";
|
||||||
"The time when the most recent RIPng update was
|
}
|
||||||
received from this neighbor.";
|
leaf last-update {
|
||||||
}
|
type yang:date-and-time;
|
||||||
leaf bad-packets-rcvd {
|
description
|
||||||
type yang:counter32;
|
"The time when the most recent RIPng update was
|
||||||
description
|
received from this neighbor.";
|
||||||
"The number of RIPng invalid packets received from
|
}
|
||||||
this neighbor which were subsequently discarded
|
leaf bad-packets-rcvd {
|
||||||
for any reason (e.g. a version 0 packet, or an
|
type yang:counter32;
|
||||||
unknown command type).";
|
description
|
||||||
}
|
"The number of RIPng invalid packets received from
|
||||||
leaf bad-routes-rcvd {
|
this neighbor which were subsequently discarded
|
||||||
type yang:counter32;
|
for any reason (e.g. a version 0 packet, or an
|
||||||
description
|
unknown command type).";
|
||||||
"The number of routes received from this neighbor,
|
}
|
||||||
in valid RIPng packets, which were ignored for any
|
leaf bad-routes-rcvd {
|
||||||
reason (e.g. unknown address family, or invalid
|
type yang:counter32;
|
||||||
metric).";
|
description
|
||||||
|
"The number of routes received from this neighbor,
|
||||||
|
in valid RIPng packets, which were ignored for any
|
||||||
|
reason (e.g. unknown address family, or invalid
|
||||||
|
metric).";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
container routes {
|
||||||
container routes {
|
|
||||||
description
|
|
||||||
"Route information.";
|
|
||||||
list route {
|
|
||||||
key "prefix";
|
|
||||||
description
|
description
|
||||||
"A RIPng IPv6 route.";
|
"Route information.";
|
||||||
leaf prefix {
|
list route {
|
||||||
type inet:ipv6-prefix;
|
key "prefix";
|
||||||
description
|
description
|
||||||
"IPv6 address and prefix length, in the format
|
"A RIPng IPv6 route.";
|
||||||
specified in RFC6991.";
|
leaf prefix {
|
||||||
}
|
type inet:ipv6-prefix;
|
||||||
leaf next-hop {
|
description
|
||||||
type inet:ipv6-address;
|
"IPv6 address and prefix length, in the format
|
||||||
description
|
specified in RFC6991.";
|
||||||
"Next hop IPv6 address.";
|
}
|
||||||
}
|
leaf next-hop {
|
||||||
leaf interface {
|
type inet:ipv6-address;
|
||||||
type string;
|
description
|
||||||
description
|
"Next hop IPv6 address.";
|
||||||
"The interface that the route uses.";
|
}
|
||||||
}
|
leaf interface {
|
||||||
leaf metric {
|
type string;
|
||||||
type uint8 {
|
description
|
||||||
range "0..16";
|
"The interface that the route uses.";
|
||||||
|
}
|
||||||
|
leaf metric {
|
||||||
|
type uint8 {
|
||||||
|
range "0..16";
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"Route metric.";
|
||||||
}
|
}
|
||||||
description
|
|
||||||
"Route metric.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,5 +322,18 @@ module frr-ripngd {
|
|||||||
description
|
description
|
||||||
"Clears RIPng routes from the IPv6 routing table and routes
|
"Clears RIPng routes from the IPv6 routing table and routes
|
||||||
redistributed into the RIPng protocol.";
|
redistributed into the RIPng protocol.";
|
||||||
|
|
||||||
|
input {
|
||||||
|
leaf vrf {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"VRF name identifying a specific RIPng instance.
|
||||||
|
This leaf is optional for the rpc.
|
||||||
|
If it is specified, the rpc will clear all routes in the
|
||||||
|
specified RIPng instance;
|
||||||
|
if it is not specified, the rpc will clear all routes in
|
||||||
|
all RIPng instances.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']",
|
||||||
"native": "/frr-ripd:ripd/instance"
|
"native": "/frr-ripd:ripd/instance[vrf='default']"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -32,31 +32,31 @@
|
|||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/default-metric",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/default-metric",
|
||||||
"native": "/frr-ripd:ripd/instance/default-metric"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/default-metric"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/distance",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/distance",
|
||||||
"native": "/frr-ripd:ripd/instance/distance/default"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/distance/default"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/originate-default-route/enabled",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/originate-default-route/enabled",
|
||||||
"native": "/frr-ripd:ripd/instance/default-information-originate"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/default-information-originate"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/timers/update-interval",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/timers/update-interval",
|
||||||
"native": "/frr-ripd:ripd/instance/timers/update-interval"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/timers/update-interval"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/timers/holddown-interval",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/timers/holddown-interval",
|
||||||
"native": "/frr-ripd:ripd/instance/timers/holddown-interval"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/timers/holddown-interval"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/timers/flush-interval",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/timers/flush-interval",
|
||||||
"native": "/frr-ripd:ripd/instance/timers/flush-interval"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/timers/flush-interval"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/interfaces/interface[interface='KEY1']",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/interfaces/interface[interface='KEY1']",
|
||||||
"native": "/frr-ripd:ripd/instance/interface[.='KEY1']"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/interface[.='KEY1']"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/interfaces/interface[interface='KEY1']/split-horizon",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/interfaces/interface[interface='KEY1']/split-horizon",
|
||||||
@ -64,43 +64,43 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']",
|
||||||
"native": "/frr-ripd:ripd/state/neighbors/neighbor[address='KEY1']"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/neighbors/neighbor[address='KEY1']"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/ipv4-address",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/ipv4-address",
|
||||||
"native": "/frr-ripd:ripd/state/neighbors/neighbor[address='KEY1']/address"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/neighbors/neighbor[address='KEY1']/address"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/last-update",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/last-update",
|
||||||
"native": "/frr-ripd:ripd/state/neighbors/neighbor[address='KEY1']/last-update"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/neighbors/neighbor[address='KEY1']/last-update"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/bad-packets-rcvd",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/bad-packets-rcvd",
|
||||||
"native": "/frr-ripd:ripd/state/neighbors/neighbor[address='KEY1']/bad-packets-rcvd"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/neighbors/neighbor[address='KEY1']/bad-packets-rcvd"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/bad-routes-rcvd",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/neighbors/neighbor[ipv4-address='KEY1']/bad-routes-rcvd",
|
||||||
"native": "/frr-ripd:ripd/state/neighbors/neighbor[address='KEY1']/bad-routes-rcvd"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/neighbors/neighbor[address='KEY1']/bad-routes-rcvd"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']",
|
||||||
"native": "/frr-ripd:ripd/state/routes/route[prefix='KEY1']"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/routes/route[prefix='KEY1']"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/ipv4-prefix",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/ipv4-prefix",
|
||||||
"native": "/frr-ripd:ripd/state/routes/route[prefix='KEY1']/prefix"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/routes/route[prefix='KEY1']/prefix"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/next-hop",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/next-hop",
|
||||||
"native": "/frr-ripd:ripd/state/routes/route[prefix='KEY1']/next-hop"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/routes/route[prefix='KEY1']/next-hop"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/interface",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/interface",
|
||||||
"native": "/frr-ripd:ripd/state/routes/route[prefix='KEY1']/interface"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/routes/route[prefix='KEY1']/interface"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/metric",
|
"custom": "/ietf-routing:routing/control-plane-protocols/control-plane-protocol[type='ietf-rip:ripv2'][name='main']/ietf-rip:rip/ipv4/routes/route[ipv4-prefix='KEY1']/metric",
|
||||||
"native": "/frr-ripd:ripd/state/routes/route[prefix='KEY1']/metric"
|
"native": "/frr-ripd:ripd/instance[vrf='default']/state/routes/route[prefix='KEY1']/metric"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"custom": "/ietf-rip:clear-rip-route",
|
"custom": "/ietf-rip:clear-rip-route",
|
||||||
|
Loading…
Reference in New Issue
Block a user