Merge pull request #1111 from chiragshah6/mdev

ospfd: OSPFv2 VRF Support
This commit is contained in:
Jafar Al-Gharaibeh 2017-10-03 13:09:59 -05:00 committed by GitHub
commit 5efddfb813
31 changed files with 1859 additions and 727 deletions

1
ospfd/.gitignore vendored
View File

@ -15,3 +15,4 @@ TAGS
*~
*.loT
*.a
*.clippy.c

View File

@ -91,7 +91,7 @@ static void ospf_area_range_delete(struct ospf_area *area,
struct ospf_area_range *range = rn->info;
if (range->specifics != 0)
ospf_delete_discard_route(area->ospf->new_table,
ospf_delete_discard_route(area->ospf, area->ospf->new_table,
(struct prefix_ipv4 *)&rn->p);
ospf_area_range_free(range);
@ -1684,12 +1684,12 @@ static void ospf_abr_manage_discard_routes(struct ospf *ospf)
if (CHECK_FLAG(range->flags,
OSPF_AREA_RANGE_ADVERTISE)) {
if (range->specifics)
ospf_add_discard_route(
ospf_add_discard_route(ospf,
ospf->new_table, area,
(struct prefix_ipv4
*)&rn->p);
else
ospf_delete_discard_route(
ospf_delete_discard_route(ospf,
ospf->new_table,
(struct prefix_ipv4
*)&rn->p);

View File

@ -80,9 +80,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_addr(struct in_addr address)
{
struct listnode *node, *nnode;
struct ospf_interface *oi;
struct ospf *ospf;
struct ospf *ospf = NULL;
if (!(ospf = ospf_lookup()))
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf)
return NULL;
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
@ -97,9 +98,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp)
{
struct listnode *node, *nnode;
struct ospf_interface *oi;
struct ospf *ospf;
struct ospf *ospf = NULL;
if (!(ospf = ospf_lookup()))
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf)
return NULL;
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
@ -999,7 +1001,7 @@ void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv)
struct ospf_interface *oi;
struct registered_opaque_type *r;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
/* Check if this interface is indeed ready for type 9 */
@ -1047,7 +1049,7 @@ void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv)
struct ospf *ospf;
struct ospf_area *area;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
struct registered_opaque_type *r;
@ -1094,7 +1096,7 @@ void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv)
struct ospf *ospf;
struct registered_opaque_type *r;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Can type 11 be originated? */
if (!ospf_apiserver_is_ready_type11(ospf))
@ -1271,7 +1273,7 @@ int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv,
struct ospf *ospf;
struct ospf_area *area;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Get request sequence number */
seqnum = msg_get_seq(msg);
@ -1374,7 +1376,11 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
struct ospf *ospf;
ospf = ospf_lookup();
if (oi && oi->ospf)
ospf = oi->ospf;
else
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Create a stream for internal opaque LSA */
@ -1429,6 +1435,7 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
new->area = area;
new->oi = oi;
new->vrf_id = ospf->vrf_id;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, newlsa, length);
@ -1497,7 +1504,7 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv,
int ready = 0;
int rc = 0;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Extract opaque LSA data from message */
omsg = (struct msg_originate_request *)STREAM_DATA(msg->s);
@ -1640,7 +1647,7 @@ void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa)
case OSPF_OPAQUE_AS_LSA: {
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Increment counters? XXX */
@ -1656,7 +1663,7 @@ int ospf_apiserver_originate1(struct ospf_lsa *lsa)
{
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Install this LSA into LSDB. */
@ -1726,7 +1733,7 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa)
struct ospf_lsa *new = NULL;
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
apiserv = lookup_apiserver_by_lsa(lsa);
@ -1810,7 +1817,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
int rc = 0;
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Extract opaque LSA from message */
@ -1862,7 +1869,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
* the LSDB until it is finally handled by the maxage remover thread.
* Therefore, the lookup function below may return non-NULL result.
*/
old = ospf_lsa_lookup(area, dmsg->lsa_type, id, ospf->router_id);
old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id);
if (!old) {
zlog_warn(
"ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
@ -1923,7 +1930,7 @@ void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
struct ospf *ospf;
struct ospf_area *area;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Set parameter struct. */

View File

@ -58,7 +58,8 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)
/* Remove route from zebra. */
if (or->type == OSPF_DESTINATION_NETWORK)
ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
ospf_zebra_delete(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
ospf_route_free(or);

View File

@ -598,7 +598,8 @@ static int ospf_ase_route_match_same(struct route_table *rt,
return 1;
}
static int ospf_ase_compare_tables(struct route_table *new_external_route,
static int ospf_ase_compare_tables(struct ospf *ospf,
struct route_table *new_external_route,
struct route_table *old_external_route)
{
struct route_node *rn, *new_rn;
@ -609,7 +610,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route,
if ((or = rn->info)) {
if (!(new_rn = route_node_lookup(new_external_route,
&rn->p)))
ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
ospf_zebra_delete(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
else
route_unlock_node(new_rn);
@ -621,7 +623,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route,
if ((or = rn->info) != NULL)
if (!ospf_ase_route_match_same(old_external_route,
&rn->p, or))
ospf_zebra_add((struct prefix_ipv4 *)&rn->p,
ospf_zebra_add(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
return 0;
@ -666,7 +669,7 @@ static int ospf_ase_calculate_timer(struct thread *t)
/* Compare old and new external routing table and install the
difference info zebra/kernel */
ospf_ase_compare_tables(ospf->new_external_route,
ospf_ase_compare_tables(ospf, ospf->new_external_route,
ospf->old_external_route);
/* Delete old external routing table */
@ -814,7 +817,7 @@ void ospf_ase_incremental_update(struct ospf *ospf, struct ospf_lsa *lsa)
}
/* install changes to zebra */
ospf_ase_compare_tables(ospf->new_external_route, tmp_old);
ospf_ase_compare_tables(ospf, ospf->new_external_route, tmp_old);
/* update ospf->old_external_route table */
if (rn && rn->info)

View File

@ -75,12 +75,13 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
bfd_info = (struct bfd_info *)params->bfd_info;
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug("%s nbr (%s) with BFD",
zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s",
bfd_get_command_dbg_str(command),
inet_ntoa(nbr->src));
inet_ntoa(nbr->src),
ospf_vrf_id_to_name(oi->ospf->vrf_id));
bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name,
0, 0, command, 0, VRF_DEFAULT);
0, 0, command, 0, oi->ospf->vrf_id);
}
/*
@ -158,7 +159,7 @@ static int ospf_bfd_nbr_replay(int command, struct zclient *zclient,
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
/* Replay the neighbor, if BFD is enabled in BGP */
/* Replay the neighbor, if BFD is enabled in OSPF */
for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) {
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) {
if ((nbrs = oi->nbrs) == NULL)

View File

@ -1604,9 +1604,10 @@ DEFUN_NOSH (show_debugging_ospf,
DEBUG_STR
OSPF_STR)
{
struct ospf *ospf;
struct ospf *ospf = NULL;
if ((ospf = ospf_lookup()) == NULL)
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return CMD_SUCCESS;
return show_debugging_ospf_common(vty, ospf);
@ -1651,7 +1652,8 @@ static int config_write_debug(struct vty *vty)
char str[16];
memset(str, 0, 16);
if ((ospf = ospf_lookup()) == NULL)
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return CMD_SUCCESS;
if (ospf->instance)

View File

@ -77,7 +77,8 @@ static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr,
}
/* Check LSA is related to external info. */
struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
struct external_info *ospf_external_info_check(struct ospf *ospf,
struct ospf_lsa *lsa)
{
struct as_external_lsa *al;
struct prefix_ipv4 p;
@ -96,11 +97,11 @@ struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
redist_on =
is_prefix_default(&p)
? vrf_bitmap_check(zclient->default_information,
VRF_DEFAULT)
ospf->vrf_id)
: (zclient->mi_redist[AFI_IP][type].enabled
|| vrf_bitmap_check(
zclient->redist[AFI_IP][type],
VRF_DEFAULT));
ospf->vrf_id));
// Pending: check for MI above.
if (redist_on) {
struct list *ext_list;
@ -205,7 +206,7 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf,
ospf_translated_nssa_refresh(ospf, NULL, new);
return;
}
ei = ospf_external_info_check(new);
ei = ospf_external_info_check(ospf, new);
if (ei)
ospf_external_lsa_refresh(ospf, new, ei,
LSA_REFRESH_FORCE);

View File

@ -61,7 +61,8 @@ extern void ospf_flood_lsa_as(struct ospf_lsa *);
extern void ospf_lsa_flush_area(struct ospf_lsa *, struct ospf_area *);
extern void ospf_lsa_flush_as(struct ospf *, struct ospf_lsa *);
extern void ospf_lsa_flush(struct ospf *, struct ospf_lsa *);
extern struct external_info *ospf_external_info_check(struct ospf_lsa *);
extern struct external_info *ospf_external_info_check(struct ospf *,
struct ospf_lsa *);
extern void ospf_lsdb_init(struct ospf_lsdb *);

View File

@ -243,6 +243,11 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
oi->ospf = ospf;
QOBJ_REG(oi, ospf_interface);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf interface %s vrf %s id %u created",
__PRETTY_FUNCTION__, ifp->name,
ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
return oi;
}
@ -313,6 +318,12 @@ void ospf_if_free(struct ospf_interface *oi)
list_free(oi->ls_ack);
list_free(oi->ls_ack_direct.ls_ack);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
__PRETTY_FUNCTION__, oi->ifp->name,
ospf_vrf_id_to_name(oi->ifp->vrf_id),
oi->ifp->vrf_id);
ospf_delete_from_if(oi->ifp, oi);
listnode_delete(oi->ospf->oiflist, oi);
@ -335,7 +346,11 @@ struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
struct ospf *ospf;
struct ospf_interface *oi;
if ((ospf = ospf_lookup()) == NULL)
if (!oic)
return NULL;
ospf = oic->ospf;
if (ospf == NULL)
return NULL;
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
@ -800,10 +815,11 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_vl_new(): creating pseudo zebra interface");
zlog_debug("ospf_vl_new(): creating pseudo zebra interface vrf id %u",
ospf->vrf_id);
snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count);
vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT);
vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id);
/*
* if_create sets ZEBRA_INTERFACE_LINKDETECTION
* virtual links don't need this.
@ -1164,7 +1180,6 @@ u_char ospf_default_iftype(struct interface *ifp)
void ospf_if_init()
{
/* Initialize Zebra interface data structure. */
om->iflist = vrf_iflist(VRF_DEFAULT);
hook_register_prio(if_add, 0, ospf_if_new_hook);
hook_register_prio(if_del, 0, ospf_if_delete_hook);
}

View File

@ -161,6 +161,7 @@ struct ospf_lsa *ospf_lsa_new()
monotime(&new->tv_recv);
new->tv_orig = new->tv_recv;
new->refresh_list = -1;
new->vrf_id = VRF_DEFAULT;
return new;
}
@ -786,6 +787,7 @@ static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area)
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
new->vrf_id = area->ospf->vrf_id;
/* Copy LSA data to store, discard stream. */
new->data = ospf_lsa_data_new(length);
@ -1001,6 +1003,7 @@ static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi)
new->area = oi->area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
new->vrf_id = oi->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
@ -1180,6 +1183,7 @@ static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area,
new = ospf_lsa_new();
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
new->vrf_id = area->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
@ -1321,6 +1325,7 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area,
new = ospf_lsa_new();
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
new->vrf_id = area->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
@ -1627,6 +1632,7 @@ static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf,
new->area = NULL;
SET_FLAG(new->flags,
OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
new->vrf_id = ospf->vrf_id;
/* Copy LSA data to store, discard stream. */
new->data = ospf_lsa_data_new(length);
@ -2121,14 +2127,15 @@ int ospf_default_originate_timer(struct thread *thread)
void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct listnode *node, *nnode;
struct ospf_lsa *lsa;
struct ospf_lsa *lsa = NULL;
struct ospf_area *area;
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
if (area->external_routing == OSPF_AREA_NSSA) {
if (!(lsa = ospf_lsa_lookup(area, OSPF_AS_NSSA_LSA,
p->prefix,
ospf->router_id))) {
lsa = ospf_lsa_lookup(ospf, area,
OSPF_AS_NSSA_LSA, p->prefix,
ospf->router_id);
if (!lsa) {
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
zlog_debug(
"LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
@ -3046,11 +3053,12 @@ struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, u_char type,
return lsa;
}
struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *area, u_int32_t type,
struct in_addr id, struct in_addr adv_router)
struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area,
u_int32_t type, struct in_addr id,
struct in_addr adv_router)
{
struct ospf *ospf = ospf_lookup();
assert(ospf);
if (!ospf)
return NULL;
switch (type) {
case OSPF_ROUTER_LSA:
@ -3120,7 +3128,8 @@ struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area,
* they two were forming a unique LSA-ID.
*/
match = ospf_lsa_lookup(area, lsah->type, lsah->id, lsah->adv_router);
match = ospf_lsa_lookup(area->ospf, area, lsah->type, lsah->id,
lsah->adv_router);
if (match == NULL)
if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
@ -3536,7 +3545,7 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
*/
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
break;
ei = ospf_external_info_check(lsa);
ei = ospf_external_info_check(ospf, lsa);
if (ei)
new = ospf_external_lsa_refresh(ospf, lsa, ei,
LSA_REFRESH_FORCE);

View File

@ -111,6 +111,9 @@ struct ospf_lsa {
/* For Type-9 Opaque-LSAs */
struct ospf_interface *oi;
/* VRF Id */
vrf_id_t vrf_id;
};
/* OSPF LSA Link Type. */
@ -267,8 +270,9 @@ extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *,
struct external_info *);
extern int ospf_external_lsa_originate_timer(struct thread *);
extern int ospf_default_originate_timer(struct thread *);
extern struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *, u_int32_t,
struct in_addr, struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
u_int32_t, struct in_addr,
struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, u_int32_t,
struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *,

View File

@ -187,7 +187,7 @@ int main(int argc, char **argv)
/* Library inits. */
debug_init();
vrf_init(NULL, NULL, NULL, NULL);
ospf_vrf_init();
access_list_init();
prefix_list_init();

View File

@ -153,7 +153,10 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
if (ret < 0)
zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
top->fd, safe_strerror(errno));
#ifndef GNU_LINUX
/* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
* packet out of ifindex. Below would be used Non Linux system.
*/
ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
if (ret < 0)
zlog_warn(
@ -161,23 +164,53 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
"ifindex %u): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex,
safe_strerror(errno));
#endif
return ret;
}
int ospf_sock_init(void)
int ospf_bind_vrfdevice(struct ospf *ospf, int ospf_sock)
{
int ret = 0;
#ifdef SO_BINDTODEVICE
if (ospf && ospf->vrf_id != VRF_DEFAULT &&
ospf->vrf_id != VRF_UNKNOWN) {
ret = setsockopt(ospf_sock, SOL_SOCKET, SO_BINDTODEVICE,
ospf->name,
strlen(ospf->name));
if (ret < 0) {
int save_errno = errno;
zlog_warn("%s: Could not setsockopt SO_BINDTODEVICE %s",
__PRETTY_FUNCTION__,
safe_strerror(save_errno));
} else {
zlog_debug("%s: Bind socket %d to vrf %s id %u device",
__PRETTY_FUNCTION__, ospf_sock,
ospf->name, ospf->vrf_id);
}
}
#endif
return ret;
}
int ospf_sock_init(struct ospf *ospf)
{
int ospf_sock;
int ret, hincl = 1;
int bufsize = (8 * 1024 * 1024);
if (ospfd_privs.change(ZPRIVS_RAISE))
if (ospfd_privs.change(ZPRIVS_RAISE)) {
zlog_err("ospf_sock_init: could not raise privs, %s",
safe_strerror(errno));
}
ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
if (ospf_sock < 0) {
int save_errno = errno;
if (ospfd_privs.change(ZPRIVS_LOWER))
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
@ -186,17 +219,20 @@ int ospf_sock_init(void)
exit(1);
}
ret = ospf_bind_vrfdevice(ospf, ospf_sock);
if (ret < 0)
goto out;
#ifdef IP_HDRINCL
/* we will include IP header with packet */
ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
sizeof(hincl));
if (ret < 0) {
int save_errno = errno;
if (ospfd_privs.change(ZPRIVS_LOWER))
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
ospf_sock, safe_strerror(save_errno));
goto out;
}
#elif defined(IPTOS_PREC_INTERNETCONTROL)
#warning "IP_HDRINCL not available on this system"
@ -204,13 +240,11 @@ int ospf_sock_init(void)
ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL);
if (ret < 0) {
int save_errno = errno;
if (ospfd_privs.change(ZPRIVS_LOWER))
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos,
ospf_sock, safe_strerror(save_errno));
close(ospf_sock); /* Prevent sd leak. */
return ret;
goto out;
}
#else /* !IPTOS_PREC_INTERNETCONTROL */
#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
@ -222,13 +256,14 @@ int ospf_sock_init(void)
if (ret < 0)
zlog_warn("Can't set pktinfo option for fd %d", ospf_sock);
setsockopt_so_sendbuf(ospf_sock, bufsize);
setsockopt_so_recvbuf(ospf_sock, bufsize);
ospf->fd = ospf_sock;
out:
if (ospfd_privs.change(ZPRIVS_LOWER)) {
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
}
setsockopt_so_sendbuf(ospf_sock, bufsize);
setsockopt_so_recvbuf(ospf_sock, bufsize);
return ospf_sock;
return ret;
}

View File

@ -29,6 +29,7 @@ extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *,
extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_sock_init(void);
extern int ospf_sock_init(struct ospf *ospf);
extern int ospf_bind_vrfdevice(struct ospf *, int);
#endif /* _ZEBRA_OSPF_NETWORK_H */

View File

@ -544,7 +544,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
listnode_add(new->area->opaque_lsa_self, oipt);
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) {
free_opaque_info_per_type((void *)oipt);
oipt = NULL;
@ -648,7 +648,7 @@ lookup_opaque_info_by_type(struct ospf_lsa *lsa)
"Type-10 Opaque-LSA: Reference to AREA is missing?");
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) {
zlog_warn(
"Type-11 Opaque-LSA: Reference to OSPF is missing?");
@ -1571,7 +1571,7 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc)
}
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) {
/* Above conditions must have passed. */
zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
@ -1597,7 +1597,7 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa)
struct ospf_opaque_functab *functab;
struct ospf_lsa *new = NULL;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL
|| functab->lsa_refresher == NULL) {
@ -1638,7 +1638,7 @@ static int ospf_opaque_lsa_refresh_timer(struct thread *t);
void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
u_char lsa_type, u_char opaque_type)
{
struct ospf *top;
struct ospf *top = NULL;
struct ospf_area dummy, *area = NULL;
struct ospf_interface *oi = NULL;
@ -1739,6 +1739,7 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
/* Generate a dummy lsa to be passed for a lookup function. */
lsa = pseudo_lsa(oi, area, lsa_type, opaque_type);
lsa->vrf_id = top->vrf_id;
if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) {
struct ospf_opaque_functab *functab;
@ -1804,6 +1805,7 @@ static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi,
lsa.oi = oi;
lsa.area = area;
lsa.data = &lsah;
lsa.vrf_id = VRF_DEFAULT;
lsah.type = lsa_type;
tmp = SET_OPAQUE_LSID(opaque_type, 0); /* Opaque-ID is unused here. */
@ -2000,7 +2002,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0)
ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa);
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
top = lsa0->area->ospf;
ospf_ls_retransmit_delete_nbr_as(top, lsa);
@ -2054,7 +2056,7 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0)
struct ospf_lsa *lsa;
struct ospf *top;
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {

View File

@ -649,6 +649,12 @@ static int ospf_write(struct thread *thread)
#define OSPF_WRITE_IPHL_SHIFT 2
int pkt_count = 0;
#ifdef GNU_LINUX
unsigned char cmsgbuf[64] = {};
struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
struct in_pktinfo *pi;
#endif
ospf->t_write = NULL;
node = listhead(ospf->oi_write_q);
@ -753,14 +759,28 @@ static int ospf_write(struct thread *thread)
msg.msg_namelen = sizeof(sa_dst);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
iov[0].iov_base = (char *)&iph;
iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
iov[1].iov_base = STREAM_PNT(op->s);
iov[1].iov_len = op->length;
/* Sadly we can not rely on kernels to fragment packets because of either
* IP_HDRINCL and/or multicast destination being set.
*/
#ifdef GNU_LINUX
msg.msg_control = (caddr_t)cm;
cm->cmsg_level = SOL_IP;
cm->cmsg_type = IP_PKTINFO;
cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
pi = (struct in_pktinfo *)CMSG_DATA(cm);
pi->ipi_ifindex = oi->ifp->ifindex;
msg.msg_controllen = cm->cmsg_len;
#endif
/* Sadly we can not rely on kernels to fragment packets
* because of either IP_HDRINCL and/or multicast
* destination being set.
*/
#ifdef WANT_OSPF_WRITE_FRAGMENT
if (op->length > maxdatasize)
ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
@ -907,9 +927,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Packet %s [Hello:RECV]: Options %s",
zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
inet_ntoa(ospfh->router_id),
ospf_options_dump(hello->options));
ospf_options_dump(hello->options),
ospf_vrf_id_to_name(oi->ospf->vrf_id));
/* Compare options. */
#define REJECT_IF_TBIT_ON 1 /* XXX */
@ -1556,7 +1577,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
}
/* Search proper LSA in LSDB. */
find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router);
find = ospf_lsa_lookup(oi->ospf, oi->area, ls_type, ls_id,
adv_router);
if (find == NULL) {
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
list_delete(ls_upd);
@ -1696,6 +1718,7 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
/* Create OSPF LSA instance. */
lsa = ospf_lsa_new();
lsa->vrf_id = oi->ospf->vrf_id;
/* We may wish to put some error checking if type NSSA comes in
and area not in NSSA mode */
switch (lsah->type) {
@ -1784,6 +1807,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
*/
lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size);
if (lsas == NULL)
return;
#define DISCARD_LSA(L, N) \
{ \
if (IS_DEBUG_OSPF_EVENT) \
@ -2173,6 +2198,7 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
lsa = ospf_lsa_new();
lsa->data = (struct lsa_header *)STREAM_PNT(s);
lsa->vrf_id = oi->ospf->vrf_id;
/* lsah = (struct lsa_header *) STREAM_PNT (s); */
size -= OSPF_LSA_HEADER_SIZE;
@ -2197,7 +2223,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
return;
}
static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
static struct stream *ospf_recv_packet(struct ospf *ospf, int fd,
struct interface **ifp,
struct stream *ibuf)
{
int ret;
@ -2265,7 +2292,7 @@ static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
ifindex = getsockopt_ifindex(AF_INET, &msgh);
*ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
*ifp = if_lookup_by_index(ifindex, ospf->vrf_id);
if (ret != ip_len) {
zlog_warn(
@ -2833,7 +2860,7 @@ int ospf_read(struct thread *thread)
struct ip *iph;
struct ospf_header *ospfh;
u_int16_t length;
struct interface *ifp;
struct interface *ifp = NULL;
struct connected *c;
/* first of all get interface pointer. */
@ -2844,7 +2871,8 @@ int ospf_read(struct thread *thread)
thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
stream_reset(ospf->ibuf);
if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf)))
ibuf = ospf_recv_packet(ospf, ospf->fd, &ifp, ospf->ibuf);
if (ibuf == NULL)
return -1;
/* This raw packet is known to be at least as big as its IP header. */
@ -2861,7 +2889,7 @@ int ospf_read(struct thread *thread)
ifindex
retrieval but do not. */
c = if_lookup_address((void *)&iph->ip_src, AF_INET,
VRF_DEFAULT);
ospf->vrf_id);
if (c)
ifp = c->ifp;
if (ifp == NULL)
@ -3487,6 +3515,13 @@ static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr)
op->dst.s_addr = addr;
if (IS_DEBUG_OSPF_EVENT) {
if (oi->ospf->vrf_id)
zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u",
__PRETTY_FUNCTION__, oi->ifp->name,
ospf_vrf_id_to_name(oi->ospf->vrf_id),
oi->ospf->vrf_id);
}
/* Add packet to the top of the interface output queue, so that they
* can't get delayed by things like long queues of LS Update packets
*/

View File

@ -427,7 +427,7 @@ static void initialize_params(struct ospf_router_info *ori)
/* If Area address is not null and exist, retrieve corresponding
* structure */
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
zlog_info("RI-> Initialize Router Info for %s scope within area %s",
OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS",
inet_ntoa(OspfRI.area_id));
@ -586,7 +586,7 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
"LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance",
lsa_type, inet_ntoa(lsa_id));
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Set opaque-LSA header fields. */
lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
@ -615,6 +615,11 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
scope, fulfill otherwise */
if (new->area && new->area->ospf)
new->vrf_id = new->area->ospf->vrf_id;
else
new->vrf_id = VRF_DEFAULT;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, lsah, length);
stream_free(s);
@ -628,6 +633,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
struct ospf *top;
struct ospf_area *area;
int rc = -1;
vrf_id_t vrf_id = VRF_DEFAULT;
/* First check if the area is known if flooding scope is Area */
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
@ -638,6 +644,8 @@ static int ospf_router_info_lsa_originate1(void *arg)
return rc;
}
OspfRI.area = area;
if (area->ospf)
vrf_id = area->ospf->vrf_id;
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
@ -646,9 +654,15 @@ static int ospf_router_info_lsa_originate1(void *arg)
"ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
return rc;
}
new->vrf_id = vrf_id;
/* Get ospf info */
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(vrf_id);
if (top == NULL) {
zlog_debug("%s: ospf instance not found for vrf id %u",
__PRETTY_FUNCTION__, vrf_id);
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@ -751,10 +765,11 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
new->vrf_id = lsa->vrf_id;
/* Install this LSA into LSDB. */
/* Given "lsa" will be freed in the next function. */
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
@ -800,7 +815,7 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode == REORIGINATE_THIS_LSA))
opcode = REFRESH_THIS_LSA;
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
zlog_warn(
"ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");

View File

@ -83,7 +83,7 @@ void ospf_path_free(struct ospf_path *op)
XFREE(MTYPE_OSPF_PATH, op);
}
void ospf_route_delete(struct route_table *rt)
void ospf_route_delete(struct ospf *ospf, struct route_table *rt)
{
struct route_node *rn;
struct ospf_route * or ;
@ -91,10 +91,11 @@ void ospf_route_delete(struct route_table *rt)
for (rn = route_top(rt); rn; rn = route_next(rn))
if ((or = rn->info) != NULL) {
if (or->type == OSPF_DESTINATION_NETWORK)
ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
ospf_zebra_delete(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
else if (or->type == OSPF_DESTINATION_DISCARD)
ospf_zebra_delete_discard(
ospf_zebra_delete_discard(ospf,
(struct prefix_ipv4 *)&rn->p);
}
}
@ -191,7 +192,8 @@ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix,
/* delete routes generated from AS-External routes if there is a inter/intra
* area route
*/
static void ospf_route_delete_same_ext(struct route_table *external_routes,
static void ospf_route_delete_same_ext(struct ospf *ospf,
struct route_table *external_routes,
struct route_table *routes)
{
struct route_node *rn, *ext_rn;
@ -206,7 +208,8 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes,
if ((ext_rn = route_node_lookup(external_routes,
(struct prefix *)p))) {
if (ext_rn->info) {
ospf_zebra_delete(p, ext_rn->info);
ospf_zebra_delete(ospf, p,
ext_rn->info);
ospf_route_free(ext_rn->info);
ext_rn->info = NULL;
}
@ -217,7 +220,7 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes,
}
/* rt: Old, cmprt: New */
static void ospf_route_delete_uniq(struct route_table *rt,
static void ospf_route_delete_uniq(struct ospf *ospf, struct route_table *rt,
struct route_table *cmprt)
{
struct route_node *rn;
@ -232,7 +235,7 @@ static void ospf_route_delete_uniq(struct route_table *rt,
cmprt,
(struct prefix_ipv4 *)&rn
->p))
ospf_zebra_delete(
ospf_zebra_delete(ospf,
(struct prefix_ipv4
*)&rn->p,
or);
@ -241,7 +244,7 @@ static void ospf_route_delete_uniq(struct route_table *rt,
cmprt,
(struct prefix_ipv4 *)&rn
->p))
ospf_zebra_delete_discard(
ospf_zebra_delete_discard(ospf,
(struct prefix_ipv4
*)&rn->p);
}
@ -263,9 +266,9 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
/* Delete old routes. */
if (ospf->old_table)
ospf_route_delete_uniq(ospf->old_table, rt);
ospf_route_delete_uniq(ospf, ospf->old_table, rt);
if (ospf->old_external_route)
ospf_route_delete_same_ext(ospf->old_external_route, rt);
ospf_route_delete_same_ext(ospf, ospf->old_external_route, rt);
/* Install new routes. */
for (rn = route_top(rt); rn; rn = route_next(rn))
@ -274,14 +277,14 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
if (!ospf_route_match_same(
ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
ospf_zebra_add(
ospf_zebra_add(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
} else if (or->type == OSPF_DESTINATION_DISCARD)
if (!ospf_route_match_same(
ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
ospf_zebra_add_discard(
ospf_zebra_add_discard(ospf,
(struct prefix_ipv4 *)&rn->p);
}
}
@ -906,7 +909,8 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs)
}
}
int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
struct ospf_area *area,
struct prefix_ipv4 *p)
{
struct route_node *rn;
@ -961,12 +965,13 @@ int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
new_or->path_type = OSPF_PATH_INTER_AREA;
rn->info = new_or;
ospf_zebra_add_discard(p);
ospf_zebra_add_discard(ospf, p);
return 1;
}
void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
struct prefix_ipv4 *p)
{
struct route_node *rn;
struct ospf_route * or ;
@ -1012,7 +1017,7 @@ void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
route_unlock_node(rn);
/* remove the discard entry from the rib */
ospf_zebra_delete_discard(p);
ospf_zebra_delete_discard(ospf, p);
return;
}

View File

@ -115,7 +115,7 @@ extern void ospf_path_free(struct ospf_path *);
extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *);
extern struct ospf_route *ospf_route_new(void);
extern void ospf_route_free(struct ospf_route *);
extern void ospf_route_delete(struct route_table *);
extern void ospf_route_delete(struct ospf *, struct route_table *);
extern void ospf_route_table_free(struct route_table *);
extern void ospf_route_install(struct ospf *, struct route_table *);
@ -145,9 +145,9 @@ extern void ospf_route_add(struct route_table *, struct prefix_ipv4 *,
extern void ospf_route_subst_nexthops(struct ospf_route *, struct list *);
extern void ospf_prune_unreachable_networks(struct route_table *);
extern void ospf_prune_unreachable_routers(struct route_table *);
extern int ospf_add_discard_route(struct route_table *, struct ospf_area *,
struct prefix_ipv4 *);
extern void ospf_delete_discard_route(struct route_table *,
extern int ospf_add_discard_route(struct ospf *, struct route_table *,
struct ospf_area *, struct prefix_ipv4 *);
extern void ospf_delete_discard_route(struct ospf *, struct route_table *,
struct prefix_ipv4 *);
extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *,
struct ospf_route *);

View File

@ -45,38 +45,40 @@ static void ospf_route_map_update(const char *name)
{
struct ospf *ospf;
int type;
struct listnode *n1 = NULL;
/* If OSPF instatnce does not exist, return right now. */
ospf = ospf_lookup();
if (ospf == NULL)
if (listcount(om->ospf) == 0)
return;
/* Update route-map */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
/* Update route-map */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
red_list = ospf->redist[type];
if (!red_list)
continue;
red_list = ospf->redist[type];
if (!red_list)
continue;
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP_NAME(red)
&& strcmp(ROUTEMAP_NAME(red), name) == 0) {
/* Keep old route-map. */
struct route_map *old = ROUTEMAP(red);
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP_NAME(red)
&& strcmp(ROUTEMAP_NAME(red), name) == 0) {
/* Keep old route-map. */
struct route_map *old = ROUTEMAP(red);
/* Update route-map. */
ROUTEMAP(red) = route_map_lookup_by_name(
ROUTEMAP_NAME(red));
/* Update route-map. */
ROUTEMAP(red) = route_map_lookup_by_name(
ROUTEMAP_NAME(red));
/* No update for this distribute type. */
if (old == NULL && ROUTEMAP(red) == NULL)
continue;
/* No update for this distribute type. */
if (old == NULL && ROUTEMAP(red) == NULL)
continue;
ospf_distribute_list_update(ospf, type,
red->instance);
ospf_distribute_list_update(ospf, type,
red->instance);
}
}
}
}
@ -86,26 +88,24 @@ static void ospf_route_map_event(route_map_event_t event, const char *name)
{
struct ospf *ospf;
int type;
struct listnode *n1 = NULL;
/* If OSPF instatnce does not exist, return right now. */
ospf = ospf_lookup();
if (ospf == NULL)
return;
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
red_list = ospf->redist[type];
if (!red_list)
continue;
red_list = ospf->redist[type];
if (!red_list)
continue;
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
&& !strcmp(ROUTEMAP_NAME(red), name)) {
ospf_distribute_list_update(ospf, type,
red->instance);
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
&& !strcmp(ROUTEMAP_NAME(red), name)) {
ospf_distribute_list_update(ospf, type,
red->instance);
}
}
}
}
@ -285,7 +285,7 @@ static route_map_result_t route_match_interface(void *rule,
if (type == RMAP_OSPF) {
ei = object;
ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT);
ifp = if_lookup_by_name_all_vrf((char *)rule);
if (ifp == NULL || ifp->ifindex != ei->ifindex)
return RMAP_NOMATCH;

View File

@ -532,7 +532,7 @@ static u_char *ospfGeneralGroup(struct variable *v, oid *name, size_t *length,
{
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Check whether the instance identifier is valid */
if (smux_header_generic(v, name, length, exact, var_len, write_method)
@ -661,7 +661,7 @@ static struct ospf_area *ospfAreaLookup(struct variable *v, oid name[],
struct ospf_area *area;
int len;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -765,7 +765,7 @@ static struct ospf_area *ospf_stub_area_lookup_next(struct in_addr *area_id,
struct listnode *node;
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -792,7 +792,7 @@ static struct ospf_area *ospfStubAreaLookup(struct variable *v, oid name[],
struct ospf_area *area;
int len;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -934,7 +934,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name,
oid *offset;
int offsetlen;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
#define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
@ -1084,7 +1084,7 @@ static u_char *ospfLsdbEntry(struct variable *v, oid *name, size_t *length,
memset(&router_id, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -1145,7 +1145,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v,
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (exact) {
/* Area ID + Range Network. */
@ -1239,7 +1239,7 @@ static u_char *ospfAreaRangeEntry(struct variable *v, oid *name, size_t *length,
return NULL;
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -1290,7 +1290,7 @@ static struct ospf_nbr_nbma *ospfHostLookup(struct variable *v, oid *name,
struct ospf_nbr_nbma *nbr_nbma;
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -1347,7 +1347,7 @@ static u_char *ospfHostEntry(struct variable *v, oid *name, size_t *length,
return NULL;
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -1504,7 +1504,7 @@ static struct ospf_interface *ospf_snmp_if_lookup(struct in_addr *ifaddr,
struct listnode *node;
struct ospf_snmp_if *osif;
struct ospf_interface *oi = NULL;
struct ospf *ospf = ospf_lookup();
struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) {
if (ifaddr->s_addr) {
@ -1527,7 +1527,7 @@ static struct ospf_interface *ospf_snmp_if_lookup_next(struct in_addr *ifaddr,
{
struct ospf_snmp_if *osif;
struct listnode *nn;
struct ospf *ospf = ospf_lookup();
struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
struct ospf_interface *oi = NULL;
if (ospf == NULL)
@ -1675,7 +1675,7 @@ static u_char *ospfIfEntry(struct variable *v, oid *name, size_t *length,
memset(&ifaddr, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -1845,7 +1845,7 @@ static u_char *ospfIfMetricEntry(struct variable *v, oid *name, size_t *length,
memset(&ifaddr, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -2125,7 +2125,7 @@ static struct ospf_neighbor *ospf_snmp_nbr_lookup_next(struct in_addr *nbr_addr,
struct ospf_neighbor *min = NULL;
struct ospf *ospf = ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, nn, oi)) {
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
@ -2165,7 +2165,7 @@ static struct ospf_neighbor *ospfNbrLookup(struct variable *v, oid *name,
struct ospf_neighbor *nbr;
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf)
return NULL;
@ -2325,7 +2325,7 @@ static u_char *ospfVirtNbrEntry(struct variable *v, oid *name, size_t *length,
memset(&neighbor, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@ -2379,7 +2379,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name,
struct ospf_lsa *lsa;
struct ospf *ospf;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (exact) {
if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
return NULL;
@ -2476,7 +2476,7 @@ static u_char *ospfExtLsdbEntry(struct variable *v, oid *name, size_t *length,
memset(&router_id, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;

View File

@ -781,7 +781,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
* of candidates with any vertices not already on the list. If a lower-cost
* path is found to a vertex already on the candidate list, store the new cost.
*/
static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
static void ospf_spf_next(struct vertex *v, struct ospf *ospf,
struct ospf_area *area,
struct pqueue *candidate)
{
struct ospf_lsa *w_lsa = NULL;
@ -841,7 +842,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
inet_ntoa(l->link_id));
}
w_lsa = ospf_lsa_lookup(area, OSPF_ROUTER_LSA,
w_lsa = ospf_lsa_lookup(ospf, area,
OSPF_ROUTER_LSA,
l->link_id, l->link_id);
if (w_lsa) {
if (IS_DEBUG_OSPF_EVENT)
@ -1159,7 +1161,7 @@ ospf_rtrs_print (struct route_table *rtrs)
#endif
/* Calculating the shortest-path tree for an area. */
static void ospf_spf_calculate(struct ospf_area *area,
static void ospf_spf_calculate(struct ospf *ospf, struct ospf_area *area,
struct route_table *new_table,
struct route_table *new_rtrs)
{
@ -1209,7 +1211,7 @@ static void ospf_spf_calculate(struct ospf_area *area,
for (;;) {
/* RFC2328 16.1. (2). */
ospf_spf_next(v, area, candidate);
ospf_spf_next(v, ospf, area, candidate);
/* RFC2328 16.1. (3). */
/* If at this step the candidate list is empty, the shortest-
@ -1307,13 +1309,13 @@ static int ospf_spf_calculate_timer(struct thread *thread)
if (ospf->backbone && ospf->backbone == area)
continue;
ospf_spf_calculate(area, new_table, new_rtrs);
ospf_spf_calculate(ospf, area, new_table, new_rtrs);
areas_processed++;
}
/* SPF for backbone, if required */
if (ospf->backbone) {
ospf_spf_calculate(ospf->backbone, new_table, new_rtrs);
ospf_spf_calculate(ospf, ospf->backbone, new_table, new_rtrs);
areas_processed++;
}
@ -1339,6 +1341,12 @@ static int ospf_spf_calculate_timer(struct thread *thread)
ospf_ase_calculate_timer_add(ospf);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf install new route, vrf %s id %u new_table count %lu",
__PRETTY_FUNCTION__,
ospf_vrf_id_to_name(ospf->vrf_id),
ospf->vrf_id, new_table->count);
/* Update routing table. */
monotime(&start_time);
ospf_route_install(ospf, new_table);

View File

@ -728,7 +728,7 @@ static void update_linkparams(struct mpls_te_link *lp)
else {
lp->flags = INTER_AS | FLOOD_AREA;
lp->area = ospf_area_lookup_by_area_id(
ospf_lookup(),
ospf_lookup_by_vrf_id(VRF_DEFAULT),
OspfMplsTE.interas_areaid);
}
}
@ -1127,7 +1127,8 @@ static void ospf_mpls_te_lsa_body_set(struct stream *s, struct mpls_te_link *lp)
}
/* Create new opaque-LSA. */
static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf,
struct ospf_area *area,
struct mpls_te_link *lp)
{
struct stream *s;
@ -1167,9 +1168,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance);
lsa_id.s_addr = htonl(tmp);
struct ospf *top = ospf_lookup();
if (!ospf)
return NULL;
lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
lsa_header_set(s, options, lsa_type, lsa_id, ospf->router_id);
} else {
options |= LSA_OPTIONS_GET(area); /* Get area default option */
options |= LSA_OPTIONS_NSSA_GET(area);
@ -1207,6 +1209,9 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
return new;
}
new->vrf_id = ospf->vrf_id;
if (area && area->ospf)
new->vrf_id = area->ospf->vrf_id;
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, lsah, length);
@ -1218,11 +1223,12 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
struct mpls_te_link *lp)
{
struct ospf_lsa *new;
struct ospf_lsa *new = NULL;
int rc = -1;
/* Create new Opaque-LSA/MPLS-TE instance. */
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
new = ospf_mpls_te_lsa_new(area->ospf, area, lp);
if (new == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
return rc;
@ -1321,11 +1327,13 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
int rc = -1;
/* Create new Opaque-LSA/Inter-AS instance. */
if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) {
new = ospf_mpls_te_lsa_new(top, NULL, lp);
if (new == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
return rc;
}
new->vrf_id = top->vrf_id;
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@ -1451,9 +1459,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
ospf_opaque_lsa_flush_schedule(lsa);
return NULL;
}
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
/* Create new Opaque-LSA/MPLS-TE instance. */
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
new = ospf_mpls_te_lsa_new(top, area, lp);
if (new == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
return NULL;
}
@ -1465,8 +1474,6 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
* ospf_lookup() to get ospf instance */
if (area)
top = area->ospf;
else
top = ospf_lookup();
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
@ -1500,7 +1507,7 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode)
memset(&lsa, 0, sizeof(lsa));
memset(&lsah, 0, sizeof(lsah));
top = ospf_lookup();
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Check if the pseudo link is ready to flood */
if (!(CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE))
@ -2517,29 +2524,64 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
DEFUN (show_ip_ospf_mpls_te_link,
show_ip_ospf_mpls_te_link_cmd,
"show ip ospf mpls-te interface [INTERFACE]",
"show ip ospf [vrf <NAME|all>] mpls-te interface [INTERFACE]",
SHOW_STR
IP_STR
OSPF_STR
VRF_CMD_HELP_STR
"All VRFs\n"
"MPLS-TE information\n"
"Interface information\n"
"Interface name\n")
{
int idx_interface = 5;
struct interface *ifp;
struct listnode *node, *nnode;
struct listnode *node, *nnode, *n1;
char *vrf_name = NULL;
bool all_vrf;
int inst = 0;
int idx_vrf = 0;
struct ospf *ospf = NULL;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
/* vrf input is provided could be all or specific vrf*/
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
if (!ospf->oi_running)
continue;
for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id),
node, nnode, ifp))
show_mpls_te_link_sub(vty, ifp);
}
return CMD_SUCCESS;
}
ospf = ospf_lookup_by_inst_name (inst, vrf_name);
if (ospf == NULL || !ospf->oi_running)
return CMD_SUCCESS;
for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
nnode, ifp))
show_mpls_te_link_sub(vty, ifp);
return CMD_SUCCESS;
}
/* Show All Interfaces. */
if (argc == 5) {
for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode,
ifp))
show_mpls_te_link_sub(vty, ifp);
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
if (!ospf->oi_running)
continue;
for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
nnode, ifp))
show_mpls_te_link_sub(vty, ifp);
}
}
/* Interface name is specified. */
else {
if ((ifp = if_lookup_by_name(argv[idx_interface]->arg,
VRF_DEFAULT))
== NULL)
ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg);
if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else
show_mpls_te_link_sub(vty, ifp);

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,7 @@
DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
@ -68,23 +69,33 @@ struct in_addr router_id_zebra;
static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct ospf *ospf;
struct ospf *ospf = NULL;
struct prefix router_id;
zebra_router_id_update_read(zclient->ibuf, &router_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&router_id, buf, sizeof(buf));
zlog_debug("Zebra rcvd: router id update %s", buf);
zlog_debug("Zebra rcvd: router id update %s vrf %s id %u",
buf, ospf_vrf_id_to_name(vrf_id), vrf_id);
}
router_id_zebra = router_id.u.prefix4;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf != NULL)
ospf_router_id_update(ospf);
else {
if (IS_DEBUG_OSPF_EVENT) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&router_id, buf, sizeof(buf));
zlog_debug("%s: ospf instance not found for vrf %s id %u router_id %s",
__PRETTY_FUNCTION__,
ospf_vrf_id_to_name(vrf_id), vrf_id, buf);
}
}
return 0;
}
@ -92,14 +103,18 @@ static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
static int ospf_interface_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
struct interface *ifp = NULL;
struct ospf *ospf = NULL;
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
if (ifp == NULL)
return 0;
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
"Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d",
ifp->name, ifp->vrf_id, ifp->ifindex,
"Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
assert(ifp->info);
@ -109,7 +124,11 @@ static int ospf_interface_add(int command, struct zclient *zclient,
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
}
ospf_if_update(NULL, ifp);
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (!ospf)
return 0;
ospf_if_update(ospf, ifp);
hook_call(ospf_if_update, ifp);
@ -136,8 +155,9 @@ static int ospf_interface_delete(int command, struct zclient *zclient,
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
"Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d",
ifp->name, ifp->vrf_id, ifp->ifindex,
"Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
hook_call(ospf_if_delete, ifp);
@ -160,7 +180,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s,
/* And look it up. */
return if_lookup_by_name_len(
ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT);
ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
}
static int ospf_interface_state_up(int command, struct zclient *zclient,
@ -249,6 +269,8 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct connected *c;
struct ospf *ospf = NULL;
c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
@ -258,11 +280,16 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(c->address, buf, sizeof(buf));
zlog_debug("Zebra: interface %s address add %s", c->ifp->name,
buf);
zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id),
vrf_id);
}
ospf_if_update(NULL, c->ifp);
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (!ospf)
return 0;
ospf_if_update(ospf, c->ifp);
hook_call(ospf_if_update, c->ifp);
@ -330,19 +357,41 @@ static int ospf_interface_link_params(int command, struct zclient *zclient,
return 0;
}
/* VRF update for an interface. */
static int ospf_interface_vrf_update(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp = NULL;
vrf_id_t new_vrf_id;
void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
&new_vrf_id);
if (!ifp)
return 0;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
__PRETTY_FUNCTION__, ifp->name, vrf_id,
ospf_vrf_id_to_name(new_vrf_id), new_vrf_id);
/*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
if_update_to_new_vrf(ifp, new_vrf_id);
return 0;
}
void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
struct ospf_route *or)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
u_char distance;
struct ospf_path *path;
struct listnode *node;
struct ospf *ospf = ospf_lookup();
int count = 0;
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@ -368,7 +417,7 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
}
/* Distance value. */
distance = ospf_distance_apply(p, or);
distance = ospf_distance_apply(ospf, p, or);
if (distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
api.distance = distance;
@ -413,13 +462,13 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
struct ospf_route *or)
{
struct zapi_route api;
struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@ -435,13 +484,12 @@ void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
}
void ospf_zebra_add_discard(struct prefix_ipv4 *p)
void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct zapi_route api;
struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@ -455,13 +503,12 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p)
inet_ntoa(p->prefix), p->prefixlen);
}
void ospf_zebra_delete_discard(struct prefix_ipv4 *p)
void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct zapi_route api;
struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@ -595,11 +642,11 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
}
int ospf_is_type_redistributed(int type, u_short instance)
int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance)
{
return (DEFAULT_ROUTE_TYPE(type)
? vrf_bitmap_check(zclient->default_information,
VRF_DEFAULT)
ospf->vrf_id)
: ((instance
&& redist_check_instance(
&zclient->mi_redist[AFI_IP][type],
@ -607,7 +654,7 @@ int ospf_is_type_redistributed(int type, u_short instance)
|| (!instance
&& vrf_bitmap_check(
zclient->redist[AFI_IP][type],
VRF_DEFAULT))));
ospf->vrf_id))));
}
int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
@ -617,7 +664,7 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
struct ospf_redist *red;
red = ospf_redist_lookup(ospf, type, instance);
if (ospf_is_type_redistributed(type, instance)) {
if (ospf_is_type_redistributed(ospf, type, instance)) {
if (mtype != red->dmetric.type) {
red->dmetric.type = mtype;
force = LSA_REFRESH_FORCE;
@ -645,11 +692,11 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
ospf_external_add(type, instance);
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
instance, VRF_DEFAULT);
instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[%s][%d]: Start Type[%d], Metric[%d]",
ospf_redist_string(type), instance,
zlog_debug("Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
ospf_redist_string(type), instance, ospf->vrf_id,
metric_type(ospf, type, instance),
metric_value(ospf, type, instance));
@ -663,15 +710,15 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance)
if (type == zclient->redist_default && instance == zclient->instance)
return CMD_SUCCESS;
if (!ospf_is_type_redistributed(type, instance))
if (!ospf_is_type_redistributed(ospf, type, instance))
return CMD_SUCCESS;
zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
instance, VRF_DEFAULT);
instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[%s][%d]: Stop",
ospf_redist_string(type), instance);
zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
ospf_redist_string(type), instance, ospf->vrf_id);
ospf_redist_del(ospf, type, instance);
@ -698,7 +745,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
ospf_external_add(DEFAULT_ROUTE, 0);
if (ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) {
if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
/* if ospf->default_originate changes value, is calling
ospf_external_lsa_refresh_default sufficient to implement
the change? */
@ -714,7 +761,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
}
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
VRF_DEFAULT);
ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
@ -734,14 +781,14 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
int ospf_redistribute_default_unset(struct ospf *ospf)
{
if (!ospf_is_type_redistributed(DEFAULT_ROUTE, 0))
if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
return CMD_SUCCESS;
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
VRF_DEFAULT);
ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[DEFAULT]: Stop");
@ -886,7 +933,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
struct ospf *ospf;
int i;
ospf = ospf_lookup();
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf == NULL)
return 0;
@ -1019,10 +1066,13 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
struct external_info *ei;
struct route_table *rt;
struct ospf_lsa *lsa;
int type, default_refresh = 0;
struct ospf *ospf;
int type, default_refresh = 0, arg_type;
struct ospf *ospf = NULL;
void **arg = THREAD_ARG (thread);
ospf = (struct ospf *)arg[0];
arg_type = (int)(intptr_t)arg[1];
ospf = ospf_lookup();
if (ospf == NULL)
return 0;
@ -1030,6 +1080,12 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
if (IS_DEBUG_OSPF_EVENT) {
zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d",
__PRETTY_FUNCTION__, arg_type,
ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
}
/* foreach all external info. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *ext_list;
@ -1062,15 +1118,21 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
}
if (default_refresh)
ospf_external_lsa_refresh_default(ospf);
XFREE(MTYPE_OSPF_DIST_ARGS, arg);
return 0;
}
/* Update distribute-list and set timer to apply access-list. */
void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type,
void ospf_distribute_list_update(struct ospf *ospf, int type,
u_short instance)
{
struct route_table *rt;
struct ospf_external *ext;
void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
args[0] = ospf;
args[1] = (void *)((ptrdiff_t) type);
/* External info does not exist. */
ext = ospf_external_lookup(type, instance);
@ -1084,7 +1146,7 @@ void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type,
/* Set timer. */
ospf->t_distribute_update = NULL;
thread_add_timer_msec(master, ospf_distribute_list_update_timer,
(void *)type, ospf->min_ls_interval,
(void **)args, ospf->min_ls_interval,
&ospf->t_distribute_update);
}
@ -1095,134 +1157,148 @@ static void ospf_filter_update(struct access_list *access)
int type;
int abr_inv = 0;
struct ospf_area *area;
struct listnode *node;
struct listnode *node, *n1;
/* If OSPF instance does not exist, return right now. */
ospf = ospf_lookup();
if (ospf == NULL)
if (listcount(om->ospf) == 0)
return;
/* Update distribute-list, and apply filter. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
/* Iterate all ospf [VRF] instances */
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
/* Update distribute-list, and apply filter. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
red_list = ospf->redist[type];
if (red_list)
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP(red)) {
/* if route-map is not NULL it may be
* using this access list */
ospf_distribute_list_update(
ospf, type, red->instance);
red_list = ospf->redist[type];
if (red_list)
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP(red)) {
/* if route-map is not NULL it may be
* using this access list */
ospf_distribute_list_update(
ospf,
type, red->instance);
}
}
/* There is place for route-map for default-information
* (ZEBRA_ROUTE_MAX),
* but no distribute list. */
if (type == ZEBRA_ROUTE_MAX)
break;
if (DISTRIBUTE_NAME(ospf, type)) {
/* Keep old access-list for distribute-list. */
struct access_list *old = DISTRIBUTE_LIST(ospf,
type);
/* Update access-list for distribute-list. */
DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
AFI_IP, DISTRIBUTE_NAME(ospf, type));
/* No update for this distribute type. */
if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
continue;
/* Schedule distribute-list update timer. */
if (DISTRIBUTE_LIST(ospf, type) == NULL
|| strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
== 0)
ospf_distribute_list_update(ospf, type, 0);
}
}
/* Update Area access-list. */
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
if (EXPORT_NAME(area)) {
EXPORT_LIST(area) = NULL;
abr_inv++;
}
/* There is place for route-map for default-information
* (ZEBRA_ROUTE_MAX),
* but no distribute list. */
if (type == ZEBRA_ROUTE_MAX)
break;
if (DISTRIBUTE_NAME(ospf, type)) {
/* Keep old access-list for distribute-list. */
struct access_list *old = DISTRIBUTE_LIST(ospf, type);
/* Update access-list for distribute-list. */
DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
AFI_IP, DISTRIBUTE_NAME(ospf, type));
/* No update for this distribute type. */
if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
continue;
/* Schedule distribute-list update timer. */
if (DISTRIBUTE_LIST(ospf, type) == NULL
|| strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
== 0)
ospf_distribute_list_update(ospf, type, 0);
if (IMPORT_NAME(area)) {
IMPORT_LIST(area) = NULL;
abr_inv++;
}
}
/* Schedule ABR tasks -- this will be changed -- takada. */
if (IS_OSPF_ABR(ospf) && abr_inv)
ospf_schedule_abr_task(ospf);
}
/* Update Area access-list. */
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
if (EXPORT_NAME(area)) {
EXPORT_LIST(area) = NULL;
abr_inv++;
}
if (IMPORT_NAME(area)) {
IMPORT_LIST(area) = NULL;
abr_inv++;
}
}
/* Schedule ABR tasks -- this will be changed -- takada. */
if (IS_OSPF_ABR(ospf) && abr_inv)
ospf_schedule_abr_task(ospf);
}
/* If prefix-list is updated, do some updates. */
void ospf_prefix_list_update(struct prefix_list *plist)
{
struct ospf *ospf;
struct ospf *ospf = NULL;
int type;
int abr_inv = 0;
struct ospf_area *area;
struct listnode *node;
struct listnode *node, *n1;
/* If OSPF instatnce does not exist, return right now. */
ospf = ospf_lookup();
if (ospf == NULL)
if (listcount(om->ospf) == 0)
return;
/* Update all route-maps which are used as redistribution filters.
* They might use prefix-list.
*/
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
/* Iterate all ospf [VRF] instances */
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
red_list = ospf->redist[type];
if (red_list)
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
if (ROUTEMAP(red)) {
/* if route-map is not NULL it may be
* using this prefix list */
ospf_distribute_list_update(
ospf, type, red->instance);
/* Update all route-maps which are used
* as redistribution filters.
* They might use prefix-list.
*/
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
red_list = ospf->redist[type];
if (red_list) {
for (ALL_LIST_ELEMENTS_RO(red_list,
node, red)) {
if (ROUTEMAP(red)) {
/* if route-map is not NULL
* it may be using
* this prefix list */
ospf_distribute_list_update(
ospf, type,
red->instance);
}
}
}
}
/* Update area filter-lists. */
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
/* Update filter-list in. */
if (PREFIX_NAME_IN(area))
if (strcmp(PREFIX_NAME_IN(area),
prefix_list_name(plist)) == 0) {
PREFIX_LIST_IN(area) =
prefix_list_lookup(
AFI_IP,
PREFIX_NAME_IN(area));
abr_inv++;
}
/* Update filter-list out. */
if (PREFIX_NAME_OUT(area))
if (strcmp(PREFIX_NAME_OUT(area),
prefix_list_name(plist)) == 0) {
PREFIX_LIST_IN(area) =
prefix_list_lookup(
AFI_IP,
PREFIX_NAME_OUT(area));
abr_inv++;
}
}
/* Schedule ABR task. */
if (IS_OSPF_ABR(ospf) && abr_inv)
ospf_schedule_abr_task(ospf);
}
/* Update area filter-lists. */
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
/* Update filter-list in. */
if (PREFIX_NAME_IN(area))
if (strcmp(PREFIX_NAME_IN(area),
prefix_list_name(plist))
== 0) {
PREFIX_LIST_IN(area) = prefix_list_lookup(
AFI_IP, PREFIX_NAME_IN(area));
abr_inv++;
}
/* Update filter-list out. */
if (PREFIX_NAME_OUT(area))
if (strcmp(PREFIX_NAME_OUT(area),
prefix_list_name(plist))
== 0) {
PREFIX_LIST_IN(area) = prefix_list_lookup(
AFI_IP, PREFIX_NAME_OUT(area));
abr_inv++;
}
}
/* Schedule ABR task. */
if (IS_OSPF_ABR(ospf) && abr_inv)
ospf_schedule_abr_task(ospf);
}
static struct ospf_distance *ospf_distance_new(void)
@ -1326,11 +1402,10 @@ void ospf_distance_reset(struct ospf *ospf)
}
}
u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
struct ospf_route *or)
{
struct ospf *ospf;
ospf = ospf_lookup();
if (ospf == NULL)
return 0;
@ -1353,6 +1428,37 @@ u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
return 0;
}
void ospf_zebra_vrf_register(struct ospf *ospf)
{
if (!zclient || zclient->sock < 0 || !ospf)
return;
if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: Register VRF %s id %u",
__PRETTY_FUNCTION__,
ospf_vrf_id_to_name(ospf->vrf_id),
ospf->vrf_id);
zclient_send_reg_requests(zclient, ospf->vrf_id);
}
}
void ospf_zebra_vrf_deregister(struct ospf *ospf)
{
if (!zclient || zclient->sock < 0 || !ospf)
return;
if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: De-Register VRF %s id %u",
__PRETTY_FUNCTION__,
ospf_vrf_id_to_name(ospf->vrf_id),
ospf->vrf_id);
/* Deregister for router-id, interfaces,
* redistributed routes. */
zclient_send_dereg_requests(zclient, ospf->vrf_id);
}
}
static void ospf_zebra_connected(struct zclient *zclient)
{
/* Send the client registration */
@ -1375,6 +1481,7 @@ void ospf_zebra_init(struct thread_master *master, u_short instance)
zclient->interface_address_add = ospf_interface_address_add;
zclient->interface_address_delete = ospf_interface_address_delete;
zclient->interface_link_params = ospf_interface_link_params;
zclient->interface_vrf_update = ospf_interface_vrf_update;
zclient->redistribute_route_add = ospf_zebra_read_route;
zclient->redistribute_route_del = ospf_zebra_read_route;

View File

@ -41,21 +41,24 @@ struct ospf_distance {
};
/* Prototypes */
extern void ospf_zebra_add(struct prefix_ipv4 *, struct ospf_route *);
extern void ospf_zebra_delete(struct prefix_ipv4 *, struct ospf_route *);
extern void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *,
struct ospf_route *);
extern void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *,
struct ospf_route *);
extern void ospf_zebra_add_discard(struct prefix_ipv4 *);
extern void ospf_zebra_delete_discard(struct prefix_ipv4 *);
extern void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *);
extern void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *);
extern int ospf_redistribute_check(struct ospf *, struct external_info *,
int *);
extern int ospf_distribute_check_connected(struct ospf *,
struct external_info *);
extern void ospf_distribute_list_update(struct ospf *, uintptr_t, u_short);
extern void ospf_distribute_list_update(struct ospf *, int, u_short);
extern int ospf_is_type_redistributed(int, u_short);
extern int ospf_is_type_redistributed(struct ospf *, int, u_short);
extern void ospf_distance_reset(struct ospf *);
extern u_char ospf_distance_apply(struct prefix_ipv4 *, struct ospf_route *);
extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *,
struct ospf_route *);
extern struct ospf_external *ospf_external_lookup(u_char, u_short);
extern struct ospf_external *ospf_external_add(u_char, u_short);
extern void ospf_external_del(u_char, u_short);
@ -77,6 +80,8 @@ extern int ospf_distance_set(struct vty *, struct ospf *, const char *,
extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
const char *, const char *);
extern void ospf_zebra_init(struct thread_master *, u_short);
extern void ospf_zebra_vrf_register(struct ospf *ospf);
extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))

View File

@ -67,6 +67,7 @@ struct ospf_master *om;
extern struct zclient *zclient;
extern struct in_addr router_id_zebra;
extern struct zebra_privs_t ospfd_privs;
static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
@ -118,6 +119,10 @@ void ospf_router_id_update(struct ospf *ospf)
else
router_id = router_id_zebra;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Router-ID[OLD:%s]: Update to %s",
inet_ntoa(ospf->router_id),
inet_ntoa(router_id_old));
if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
@ -204,7 +209,7 @@ void ospf_router_id_update(struct ospf *ospf)
ospf_router_lsa_update(ospf);
/* update ospf_interface's */
for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
ospf_if_update(ospf, ifp);
}
}
@ -220,9 +225,10 @@ static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2)
}
/* Allocate new ospf structure. */
static struct ospf *ospf_new(u_short instance)
static struct ospf *ospf_new(u_short instance, const char *name)
{
int i;
struct vrf *vrf = NULL;
struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
@ -230,6 +236,23 @@ static struct ospf *ospf_new(u_short instance)
new->router_id.s_addr = htonl(0);
new->router_id_static.s_addr = htonl(0);
if (name) {
new->vrf_id = VRF_UNKNOWN;
/* Freed in ospf_finish_final */
new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
vrf = vrf_lookup_by_name(new->name);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: Create new ospf instance with vrf_name %s vrf_id %d",
__PRETTY_FUNCTION__, name, new->vrf_id);
if (vrf)
ospf_vrf_link(new, vrf);
} else {
new->vrf_id = VRF_DEFAULT;
vrf = vrf_lookup_by_id(VRF_DEFAULT);
ospf_vrf_link(new, vrf);
}
ospf_zebra_vrf_register(new);
new->abr_type = OSPF_ABR_DEFAULT;
new->oiflist = list_new();
new->vlinks = list_new();
@ -286,7 +309,7 @@ static struct ospf *ospf_new(u_short instance)
new->lsa_refresh_interval, &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
if ((new->fd = ospf_sock_init()) < 0) {
if ((ospf_sock_init(new)) < 0) {
zlog_err(
"ospf_new: fatal error: ospf_sock_init was unable to open "
"a socket");
@ -313,14 +336,6 @@ static struct ospf *ospf_new(u_short instance)
return new;
}
struct ospf *ospf_lookup()
{
if (listcount(om->ospf) == 0)
return NULL;
return listgetdata((struct listnode *)listhead(om->ospf));
}
struct ospf *ospf_lookup_instance(u_short instance)
{
struct ospf *ospf;
@ -357,13 +372,33 @@ static void ospf_delete(struct ospf *ospf)
listnode_delete(om->ospf, ospf);
}
struct ospf *ospf_get()
struct ospf *ospf_lookup_by_inst_name(u_short instance, const char *name)
{
struct ospf *ospf = NULL;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
if ((ospf->instance == instance) &&
((ospf->name == NULL && name == NULL) ||
(ospf->name && name && strcmp(ospf->name, name) == 0)))
return ospf;
}
return NULL;
}
struct ospf *ospf_get(u_short instance, const char *name)
{
struct ospf *ospf;
ospf = ospf_lookup();
/* vrf name provided call inst and name based api
* in case of no name pass default ospf instance */
if (name)
ospf = ospf_lookup_by_inst_name(instance, name);
else
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL) {
ospf = ospf_new(0);
ospf = ospf_new(instance, name);
ospf_add(ospf);
if (ospf->router_id_static.s_addr == 0)
@ -381,11 +416,20 @@ struct ospf *ospf_get_instance(u_short instance)
ospf = ospf_lookup_instance(instance);
if (ospf == NULL) {
ospf = ospf_new(instance);
ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
ospf_add(ospf);
if (ospf->router_id_static.s_addr == 0)
if (ospf->router_id_static.s_addr == 0) {
if (vrf_lookup_by_id(ospf->vrf_id))
ospf_router_id_update(ospf);
else {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf VRF (id %d) is not active yet, skip router id update"
, __PRETTY_FUNCTION__,
ospf->vrf_id);
}
ospf_router_id_update(ospf);
}
ospf_opaque_type11_lsa_init(ospf);
}
@ -393,6 +437,34 @@ struct ospf *ospf_get_instance(u_short instance)
return ospf;
}
struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
{
struct vrf *vrf = NULL;
vrf = vrf_lookup_by_id(vrf_id);
if (!vrf)
return NULL;
return (vrf->info) ? (struct ospf *)vrf->info : NULL;
}
/* It should only be used when processing incoming info update from zebra.
* Other situations, it is not sufficient to lookup the ospf instance by
* vrf_name only without using the instance number.
*/
static struct ospf *ospf_lookup_by_name(const char *vrf_name)
{
struct ospf *ospf = NULL;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
if ((ospf->name == NULL && vrf_name == NULL)
|| (ospf->name && vrf_name &&
strcmp(ospf->name, vrf_name) == 0))
return ospf;
return NULL;
}
/* Handle the second half of deferred shutdown. This is called either
* from the deferred-shutdown timer thread, or directly through
* ospf_deferred_shutdown_check.
@ -519,6 +591,7 @@ static void ospf_finish_final(struct ospf *ospf)
struct listnode *node, *nnode;
int i;
u_short instance = 0;
struct vrf *vrf = NULL;
QOBJ_UNREG(ospf);
@ -550,7 +623,7 @@ static void ospf_finish_final(struct ospf *ospf)
list_delete(ospf->vlinks);
/* Remove any ospf interface config params */
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) {
struct ospf_if_params *params;
params = IF_DEF_PARAMS(ifp);
@ -562,6 +635,9 @@ static void ospf_finish_final(struct ospf *ospf)
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
ospf_if_free(oi);
/* De-Register VRF */
ospf_zebra_vrf_deregister(ospf);
/* Clear static neighbors */
for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
if ((nbr_nbma = rn->info)) {
@ -639,7 +715,7 @@ static void ospf_finish_final(struct ospf *ospf)
if (ospf->old_table)
ospf_route_table_free(ospf->old_table);
if (ospf->new_table) {
ospf_route_delete(ospf->new_table);
ospf_route_delete(ospf, ospf->new_table);
ospf_route_table_free(ospf->new_table);
}
if (ospf->old_rtrs)
@ -647,11 +723,11 @@ static void ospf_finish_final(struct ospf *ospf)
if (ospf->new_rtrs)
ospf_rtrs_free(ospf->new_rtrs);
if (ospf->new_external_route) {
ospf_route_delete(ospf->new_external_route);
ospf_route_delete(ospf, ospf->new_external_route);
ospf_route_table_free(ospf->new_external_route);
}
if (ospf->old_external_route) {
ospf_route_delete(ospf->old_external_route);
ospf_route_delete(ospf, ospf->old_external_route);
ospf_route_table_free(ospf->old_external_route);
}
if (ospf->external_lsas) {
@ -694,6 +770,17 @@ static void ospf_finish_final(struct ospf *ospf)
ospf_delete(ospf);
if (ospf->name) {
vrf = vrf_lookup_by_name(ospf->name);
if (vrf)
ospf_vrf_unlink(ospf, vrf);
XFREE(MTYPE_OSPF_TOP, ospf->name);
} else {
vrf = vrf_lookup_by_id(VRF_DEFAULT);
if (vrf)
ospf_vrf_unlink(ospf, vrf);
}
XFREE(MTYPE_OSPF_TOP, ospf);
if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
@ -883,7 +970,7 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)
struct external_info *ei;
struct ospf_external *ext;
if (ospf_is_type_redistributed(ZEBRA_ROUTE_CONNECT, 0))
if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0))
if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0))
&& EXTERNAL_INFO(ext)) {
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
@ -1004,9 +1091,10 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
*
* Otherwise, doesn't do anything different to ospf_if_update for now
*/
void ospf_interface_area_set(struct interface *ifp)
void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
{
struct ospf *ospf = ospf_get();
if (!ospf)
return;
ospf_if_update(ospf, ifp);
/* if_update does a update_redistributed */
@ -1014,19 +1102,17 @@ void ospf_interface_area_set(struct interface *ifp)
return;
}
void ospf_interface_area_unset(struct interface *ifp)
void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
{
struct route_node *rn_oi;
struct ospf *ospf;
ospf = ospf_lookup();
if (!ospf)
return; /* Ospf not ready yet */
/* Find interfaces that may need to be removed. */
for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
rn_oi = route_next(rn_oi)) {
struct ospf_interface *oi;
struct ospf_interface *oi = NULL;
if ((oi = rn_oi->info) == NULL)
continue;
@ -1174,7 +1260,7 @@ static void ospf_network_run(struct prefix *p, struct ospf_area *area)
ospf_router_id_update(area->ospf);
/* Get target interface. */
for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(area->ospf->vrf_id), node, ifp))
ospf_network_run_interface(area->ospf, ifp, p, area);
}
@ -1203,8 +1289,15 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
void ospf_if_update(struct ospf *ospf, struct interface *ifp)
{
if (!ospf)
ospf = ospf_lookup();
return;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
__PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
inet_ntoa(ospf->router_id));
/* OSPF must be ready. */
if (!ospf_is_ready(ospf))
@ -1863,3 +1956,128 @@ void ospf_master_init(struct thread_master *master)
om->ospf = list_new();
om->master = master;
}
/* Link OSPF instance to VRF. */
void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
{
ospf->vrf_id = vrf->vrf_id;
if (vrf->info != (void *)ospf)
vrf->info = (void *)ospf;
}
/* Unlink OSPF instance from VRF. */
void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
{
if (vrf->info == (void *)ospf)
vrf->info = NULL;
ospf->vrf_id = VRF_UNKNOWN;
}
/* This is hook function for vrf create called as part of vrf_init */
static int ospf_vrf_new(struct vrf *vrf)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: VRF Created: %s(%d)", __PRETTY_FUNCTION__,
vrf->name, vrf->vrf_id);
return 0;
}
/* This is hook function for vrf delete call as part of vrf_init */
static int ospf_vrf_delete(struct vrf *vrf)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: VRF Deletion: %s(%d)", __PRETTY_FUNCTION__,
vrf->name, vrf->vrf_id);
return 0;
}
/* Enable OSPF VRF instance */
static int ospf_vrf_enable(struct vrf *vrf)
{
struct ospf *ospf = NULL;
vrf_id_t old_vrf_id = VRF_DEFAULT;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: VRF %s id %d enabled",
__PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
ospf = ospf_lookup_by_name(vrf->name);
if (ospf) {
old_vrf_id = ospf->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
ospf_vrf_link(ospf, vrf);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf linked to vrf %s vrf_id %d (old id %d)",
__PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
old_vrf_id);
if (old_vrf_id != ospf->vrf_id) {
if (ospfd_privs.change(ZPRIVS_RAISE)) {
zlog_err("ospf_sock_init: could not raise privs, %s",
safe_strerror(errno));
}
if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0)
return 0;
if (ospfd_privs.change(ZPRIVS_LOWER)) {
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
}
ospf->oi_running = 1;
ospf_router_id_update(ospf);
}
}
return 0;
}
/* Disable OSPF VRF instance */
static int ospf_vrf_disable(struct vrf *vrf)
{
struct ospf *ospf = NULL;
vrf_id_t old_vrf_id = VRF_UNKNOWN;
if (vrf->vrf_id == VRF_DEFAULT)
return 0;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: VRF %s id %d disabled.",
__PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
ospf = ospf_lookup_by_name(vrf->name);
if (ospf) {
old_vrf_id = ospf->vrf_id;
/* We have instance configured, unlink
* from VRF and make it "down".
*/
ospf_vrf_unlink(ospf, vrf);
ospf->oi_running = 0;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf old_vrf_id %d unlinked",
__PRETTY_FUNCTION__, old_vrf_id);
}
/* Note: This is a callback, the VRF will be deleted by the caller. */
return 0;
}
void ospf_vrf_init(void)
{
vrf_init(ospf_vrf_new, ospf_vrf_enable,
ospf_vrf_disable, ospf_vrf_delete);
}
void ospf_vrf_terminate(void)
{
vrf_terminate();
}
const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
{
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
return vrf ? vrf->name : "NIL";
}

View File

@ -28,6 +28,7 @@
#include "filter.h"
#include "log.h"
#include "vrf.h"
#include "ospf_memory.h"
#include "ospf_dump_api.h"
@ -92,8 +93,6 @@ struct ospf_master {
/* OSPF thread master. */
struct thread_master *master;
/* Zebra interface list. */
struct list *iflist;
/* Redistributed external information. */
struct list *external[ZEBRA_ROUTE_MAX + 1];
@ -136,6 +135,9 @@ struct ospf {
struct in_addr router_id; /* Configured automatically. */
struct in_addr router_id_static; /* Configured manually. */
vrf_id_t vrf_id; /* VRF Id */
char *name; /* VRF name */
/* ABR/ASBR internal flags. */
u_char flags;
#define OSPF_FLAG_ABR 0x0001
@ -503,10 +505,12 @@ extern int ospf_zlog;
/* Prototypes. */
extern const char *ospf_redist_string(u_int route_type);
extern struct ospf *ospf_lookup(void);
extern struct ospf *ospf_lookup_instance(u_short);
extern struct ospf *ospf_get(void);
extern struct ospf *ospf_get(u_short instance, const char *name);
extern struct ospf *ospf_get_instance(u_short);
extern struct ospf *ospf_lookup_by_inst_name(u_short instance,
const char *name);
extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
extern void ospf_finish(struct ospf *);
extern void ospf_router_id_update(struct ospf *ospf);
extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
@ -559,11 +563,15 @@ extern struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *,
extern void ospf_area_add_if(struct ospf_area *, struct ospf_interface *);
extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *);
extern void ospf_interface_area_set(struct interface *);
extern void ospf_interface_area_unset(struct interface *);
extern void ospf_interface_area_set(struct ospf *, struct interface *);
extern void ospf_interface_area_unset(struct ospf *, struct interface *);
extern void ospf_route_map_init(void);
extern void ospf_master_init(struct thread_master *master);
extern void ospf_vrf_init(void);
extern void ospf_vrf_terminate(void);
extern void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf);
extern void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf);
const char *ospf_vrf_id_to_name(vrf_id_t vrf_id);
#endif /* _ZEBRA_OSPFD_H */

View File

@ -58,6 +58,9 @@ ospfdheader_HEADERS = \
# end
endif
ospfd/ospf_vty_clippy.c: $(CLIPPY_DEPS)
ospfd/ospf_vty.$(OBJEXT): ospfd/ospf_vty_clippy.c
noinst_HEADERS += \
ospfd/ospf_abr.h \
ospfd/ospf_apiserver.h \

View File

@ -1273,10 +1273,12 @@ DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng",
return CMD_SUCCESS;
}
DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, "router ospf [(1-65535)]",
DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
"router ospf [(1-65535)] [vrf NAME]",
"Enable a routing process\n"
"Start OSPF configuration\n"
"Instance ID\n")
"Instance ID\n"
VRF_CMD_HELP_STR)
{
vty->node = OSPF_NODE;
return CMD_SUCCESS;