--- embedaddon/quagga/ospfd/ospf_zebra.c 2012/10/09 09:22:29 1.1.1.2 +++ embedaddon/quagga/ospfd/ospf_zebra.c 2016/11/02 10:09:12 1.1.1.4 @@ -59,7 +59,7 @@ struct in_addr router_id_zebra; /* Router-id update message from zebra. */ static int ospf_router_id_update_zebra (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct ospf *ospf; struct prefix router_id; @@ -84,11 +84,12 @@ ospf_router_id_update_zebra (int command, struct zclie /* Inteface addition message from zebra. */ static int -ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length) +ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length, + vrf_id_t vrf_id) { struct interface *ifp; - ifp = zebra_interface_add_read (zclient->ibuf); + ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) zlog_debug ("Zebra: interface add %s index %d flags %llx metric %d mtu %d", @@ -114,7 +115,7 @@ ospf_interface_add (int command, struct zclient *zclie static int ospf_interface_delete (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct stream *s; @@ -122,7 +123,7 @@ ospf_interface_delete (int command, struct zclient *zc s = zclient->ibuf; /* zebra_interface_state_read() updates interface structure in iflist */ - ifp = zebra_interface_state_read (s); + ifp = zebra_interface_state_read (s, vrf_id); if (ifp == NULL) return 0; @@ -133,8 +134,8 @@ ospf_interface_delete (int command, struct zclient *zc if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) zlog_debug - ("Zebra: interface delete %s index %d flags %lld metric %d mtu %d", - ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); + ("Zebra: interface delete %s index %d flags %llx metric %d mtu %d", + ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); #ifdef HAVE_SNMP ospf_snmp_if_delete (ifp); @@ -149,7 +150,7 @@ ospf_interface_delete (int command, struct zclient *zc } static struct interface * -zebra_interface_if_lookup (struct stream *s) +zebra_interface_if_lookup (struct stream *s, vrf_id_t vrf_id) { char ifname_tmp[INTERFACE_NAMSIZ]; @@ -163,13 +164,13 @@ zebra_interface_if_lookup (struct stream *s) static int ospf_interface_state_up (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct ospf_interface *oi; struct route_node *rn; - ifp = zebra_interface_if_lookup (zclient->ibuf); + ifp = zebra_interface_if_lookup (zclient->ibuf, vrf_id); if (ifp == NULL) return 0; @@ -225,13 +226,13 @@ ospf_interface_state_up (int command, struct zclient * static int ospf_interface_state_down (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct ospf_interface *oi; struct route_node *node; - ifp = zebra_interface_state_read (zclient->ibuf); + ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); if (ifp == NULL) return 0; @@ -251,11 +252,11 @@ ospf_interface_state_down (int command, struct zclient static int ospf_interface_address_add (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; - c = zebra_interface_address_read (command, zclient->ibuf); + c = zebra_interface_address_read (command, zclient->ibuf, vrf_id); if (c == NULL) return 0; @@ -278,7 +279,7 @@ ospf_interface_address_add (int command, struct zclien static int ospf_interface_address_delete (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; struct interface *ifp; @@ -286,7 +287,7 @@ ospf_interface_address_delete (int command, struct zcl struct route_node *rn; struct prefix p; - c = zebra_interface_address_read (command, zclient->ibuf); + c = zebra_interface_address_read (command, zclient->ibuf, vrf_id); if (c == NULL) return 0; @@ -311,6 +312,7 @@ ospf_interface_address_delete (int command, struct zcl assert (rn->info); oi = rn->info; + route_unlock_node (rn); /* Call interface hook functions to clean up */ ospf_if_free (oi); @@ -335,7 +337,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_rou struct ospf_path *path; struct listnode *node; - if (zclient->redist[ZEBRA_ROUTE_OSPF]) + if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) { message = 0; flags = 0; @@ -354,7 +356,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_rou stream_reset (s); /* Put command, type, flags, message. */ - zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD); + zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); stream_putc (s, ZEBRA_ROUTE_OSPF); stream_putc (s, flags); stream_putc (s, message); @@ -371,8 +373,15 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_rou /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) { - if (path->nexthop.s_addr != INADDR_ANY) + if (path->nexthop.s_addr != INADDR_ANY && + path->ifindex != 0) { + stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX); + stream_put_in_addr (s, &path->nexthop); + stream_putl (s, path->ifindex); + } + else if (path->nexthop.s_addr != INADDR_ANY) + { stream_putc (s, ZEBRA_NEXTHOP_IPV4); stream_put_in_addr (s, &path->nexthop); } @@ -418,60 +427,87 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_rou void ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or) { - struct zapi_ipv4 api; + u_char message; + u_char distance; + u_char flags; + int psize; + struct stream *s; struct ospf_path *path; - struct in_addr *nexthop; - struct listnode *node, *nnode; + struct listnode *node; - if (zclient->redist[ZEBRA_ROUTE_OSPF]) + if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) { - api.type = ZEBRA_ROUTE_OSPF; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - api.ifindex_num = 0; - api.nexthop_num = 0; + message = 0; + flags = 0; + /* Distance value. */ + distance = ospf_distance_apply (p, or); + /* Make packet. */ + s = zclient->obuf; + stream_reset (s); - for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path)) - { - if (path->nexthop.s_addr != INADDR_ANY) - { - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - nexthop = &path->nexthop; - api.nexthop = &nexthop; - } - else if (if_lookup_by_index(path->ifindex)) - { - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.ifindex_num = 1; - api.ifindex = &path->ifindex; - } - else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) ) - { - zlog_debug("Zebra: no ifp %s %d", - inet_ntoa(p->prefix), - p->prefixlen); - } + /* Put command, type, flags, message. */ + zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT); + stream_putc (s, ZEBRA_ROUTE_OSPF); + stream_putc (s, flags); + stream_putc (s, message); + stream_putw (s, SAFI_UNICAST); - zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + /* Put prefix information. */ + psize = PSIZE (p->prefixlen); + stream_putc (s, p->prefixlen); + stream_write (s, (u_char *) & p->prefix, psize); - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num) - { + /* Nexthop count. */ + stream_putc (s, or->paths->count); + + /* Nexthop, ifindex, distance and metric information. */ + for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) + { + if (path->nexthop.s_addr != INADDR_ANY && + path->ifindex != 0) + { + stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX); + stream_put_in_addr (s, &path->nexthop); + stream_putl (s, path->ifindex); + } + else if (path->nexthop.s_addr != INADDR_ANY) + { + stream_putc (s, ZEBRA_NEXTHOP_IPV4); + stream_put_in_addr (s, &path->nexthop); + } + else + { + stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); + stream_putl (s, path->ifindex); + } + + if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) + { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra: Route delete %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])), + inet_ntop(AF_INET, &p->prefix, + buf[0], sizeof(buf[0])), p->prefixlen, - inet_ntop(AF_INET, *api.nexthop, + inet_ntop(AF_INET, &path->nexthop, buf[1], sizeof(buf[1]))); - } - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num) - { - zlog_debug ("Zebra: Route delete %s/%d ifindex %d", - inet_ntoa (p->prefix), - p->prefixlen, *api.ifindex); - } - } + } + } + + if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) + stream_putc (s, distance); + if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) + { + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + stream_putl (s, or->cost + or->u.ext.type2_cost); + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + stream_putl (s, or->u.ext.type2_cost); + else + stream_putl (s, or->cost); + } + + stream_putw_at (s, 0, stream_get_endp (s)); + + zclient_send_message(zclient); } } @@ -480,8 +516,9 @@ ospf_zebra_add_discard (struct prefix_ipv4 *p) { struct zapi_ipv4 api; - if (zclient->redist[ZEBRA_ROUTE_OSPF]) + if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) { + api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.flags = ZEBRA_FLAG_BLACKHOLE; api.message = 0; @@ -503,8 +540,9 @@ ospf_zebra_delete_discard (struct prefix_ipv4 *p) { struct zapi_ipv4 api; - if (zclient->redist[ZEBRA_ROUTE_OSPF]) + if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) { + api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.flags = ZEBRA_FLAG_BLACKHOLE; api.message = 0; @@ -526,7 +564,8 @@ int ospf_is_type_redistributed (int type) { return (DEFAULT_ROUTE_TYPE (type)) ? - zclient->default_information : zclient->redist[type]; + vrf_bitmap_check (zclient->default_information, VRF_DEFAULT) : \ + vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT); } int @@ -560,7 +599,7 @@ ospf_redistribute_set (struct ospf *ospf, int type, in ospf->dmetric[type].type = mtype; ospf->dmetric[type].value = mvalue; - zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type); + zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT); if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]", @@ -581,7 +620,7 @@ ospf_redistribute_unset (struct ospf *ospf, int type) if (!ospf_is_type_redistributed (type)) return CMD_SUCCESS; - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type); + zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, VRF_DEFAULT); if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) zlog_debug ("Redistribute[%s]: Stop", @@ -621,7 +660,8 @@ ospf_redistribute_default_set (struct ospf *ospf, int return CMD_SUCCESS; } - zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient); + zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, + VRF_DEFAULT); if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]", @@ -648,7 +688,8 @@ ospf_redistribute_default_unset (struct ospf *ospf) ospf->dmetric[DEFAULT_ROUTE].type = -1; ospf->dmetric[DEFAULT_ROUTE].value = -1; - zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient); + zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, + VRF_DEFAULT); if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) zlog_debug ("Redistribute[DEFAULT]: Stop"); @@ -782,7 +823,7 @@ ospf_routemap_unset (struct ospf *ospf, int type) /* Zebra route add and delete treatment. */ static int ospf_zebra_read_ipv4 (int command, struct zclient *zclient, - zebra_size_t length) + zebra_size_t length, vrf_id_t vrf_id) { struct stream *s; struct zapi_ipv4 api; @@ -791,6 +832,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zcl struct prefix_ipv4 p; struct external_info *ei; struct ospf *ospf; + unsigned char plength = 0; s = zclient->ibuf; ifindex = 0; @@ -804,7 +846,8 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zcl /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; - p.prefixlen = stream_getc (s); + plength = stream_getc (s); + p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); if (IPV4_NET127(ntohl(p.prefix.s_addr))) @@ -884,8 +927,8 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zcl return 0; } - + int ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name) { @@ -966,11 +1009,9 @@ ospf_distribute_list_update_timer (struct thread *thre return 0; } -#define OSPF_DISTRIBUTE_UPDATE_DELAY 5 - /* Update distribute-list and set timer to apply access-list. */ void -ospf_distribute_list_update (struct ospf *ospf, int type) +ospf_distribute_list_update (struct ospf *ospf, uintptr_t type) { struct route_table *rt; @@ -984,8 +1025,8 @@ ospf_distribute_list_update (struct ospf *ospf, int ty /* Set timer. */ ospf->t_distribute_update = - thread_add_timer (master, ospf_distribute_list_update_timer, - (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY); + thread_add_timer_msec (master, ospf_distribute_list_update_timer, + (void *) type, ospf->min_ls_interval); } /* If access-list is updated, apply some check. */ @@ -1092,7 +1133,7 @@ ospf_prefix_list_update (struct prefix_list *plist) { /* Update filter-list in. */ if (PREFIX_NAME_IN (area)) - if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0) + if (strcmp (PREFIX_NAME_IN (area), prefix_list_name (plist)) == 0) { PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area)); @@ -1101,7 +1142,7 @@ ospf_prefix_list_update (struct prefix_list *plist) /* Update filter-list out. */ if (PREFIX_NAME_OUT (area)) - if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0) + if (strcmp (PREFIX_NAME_OUT (area), prefix_list_name (plist)) == 0) { PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area)); @@ -1183,7 +1224,6 @@ ospf_distance_unset (struct vty *vty, struct ospf *osp { int ret; struct prefix_ipv4 p; - u_char distance; struct route_node *rn; struct ospf_distance *odistance; @@ -1194,8 +1234,6 @@ ospf_distance_unset (struct vty *vty, struct ospf *osp return CMD_WARNING; } - distance = atoi (distance_str); - rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p); if (!rn) { @@ -1261,12 +1299,19 @@ ospf_distance_apply (struct prefix_ipv4 *p, struct osp return 0; } +static void +ospf_zebra_connected (struct zclient *zclient) +{ + zclient_send_requests (zclient, VRF_DEFAULT); +} + void -ospf_zebra_init () +ospf_zebra_init (struct thread_master *master) { /* Allocate zebra structure. */ - zclient = zclient_new (); + zclient = zclient_new (master); zclient_init (zclient, ZEBRA_ROUTE_OSPF); + zclient->zebra_connected = ospf_zebra_connected; zclient->router_id_update = ospf_router_id_update_zebra; zclient->interface_add = ospf_interface_add; zclient->interface_delete = ospf_interface_delete;