]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/redistribute.c
zebra: reorganize zserv, batch i/o
[mirror_frr.git] / zebra / redistribute.c
index fdfaa69571e326696b7bad94e0379f3b1982b69d..5a239306fbfae0fbd2ec6e19e04d111fe8d8a026 100644 (file)
@@ -63,20 +63,6 @@ int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
        return 0;
 }
 
-int is_default(struct prefix *p)
-{
-       if (p->family == AF_INET)
-               if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
-                       return 1;
-#if 0  /* IPv6 default separation is now pending until protocol daemon         \
-         can handle that. */
-  if (p->family == AF_INET6)
-    if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
-      return 1;
-#endif /* 0 */
-       return 0;
-}
-
 static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
 {
        int afi;
@@ -98,11 +84,13 @@ static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
                if (!rn)
                        continue;
 
-               RNODE_FOREACH_RE(rn, newre)
-               if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
-                   && newre->distance != DISTANCE_INFINITY)
-                       zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
-                                                client, &rn->p, NULL, newre);
+               RNODE_FOREACH_RE (rn, newre) {
+                       if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
+                           && newre->distance != DISTANCE_INFINITY)
+                               zsend_redistribute_route(
+                                       ZEBRA_REDISTRIBUTE_ROUTE_ADD, client,
+                                       &rn->p, NULL, newre);
+               }
 
                route_unlock_node(rn);
        }
@@ -121,8 +109,7 @@ static void zebra_redistribute(struct zserv *client, int type, u_short instance,
                return;
 
        for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
-               RNODE_FOREACH_RE(rn, newre)
-               {
+               RNODE_FOREACH_RE (rn, newre) {
                        struct prefix *dst_p, *src_p;
                        srcdest_rnode_prefixes(rn, &dst_p, &src_p);
 
@@ -181,7 +168,7 @@ void redistribute_update(struct prefix *p, struct prefix *src_p,
        for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
                send_redistribute = 0;
 
-               if (is_default(p)
+               if (is_default_prefix(p)
                    && vrf_bitmap_check(client->redist_default, re->vrf_id))
                        send_redistribute = 1;
                else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
@@ -240,7 +227,7 @@ void redistribute_delete(struct prefix *p, struct prefix *src_p,
        }
 
        for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
-               if ((is_default(p)
+               if ((is_default_prefix(p)
                     && vrf_bitmap_check(client->redist_default, re->vrf_id))
                    || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
                                        re->vrf_id)
@@ -256,19 +243,27 @@ void redistribute_delete(struct prefix *p, struct prefix *src_p,
        }
 }
 
-void zebra_redistribute_add(int command, struct zserv *client, int length,
-                           struct zebra_vrf *zvrf)
+void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
 {
-       afi_t afi;
-       int type;
+       afi_t afi = 0;
+       int type = 0;
        u_short instance;
 
-       afi = stream_getc(client->ibuf);
-       type = stream_getc(client->ibuf);
-       instance = stream_getw(client->ibuf);
+       STREAM_GETC(msg, afi);
+       STREAM_GETC(msg, type);
+       STREAM_GETW(msg, instance);
 
-       if (type == 0 || type >= ZEBRA_ROUTE_MAX)
+       if (afi == 0 || afi > AFI_MAX) {
+               zlog_warn("%s: Specified afi %d does not exist",
+                         __PRETTY_FUNCTION__, afi);
                return;
+       }
+
+       if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
+               zlog_warn("%s: Specified Route Type %d does not exist",
+                         __PRETTY_FUNCTION__, type);
+               return;
+       }
 
        if (instance) {
                if (!redist_check_instance(&client->mi_redist[afi][type],
@@ -286,21 +281,32 @@ void zebra_redistribute_add(int command, struct zserv *client, int length,
                        zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
                }
        }
+
+stream_failure:
+       return;
 }
 
-void zebra_redistribute_delete(int command, struct zserv *client, int length,
-                              struct zebra_vrf *zvrf)
+void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
 {
-       afi_t afi;
-       int type;
+       afi_t afi = 0;
+       int type = 0;
        u_short instance;
 
-       afi = stream_getc(client->ibuf);
-       type = stream_getc(client->ibuf);
-       instance = stream_getw(client->ibuf);
+       STREAM_GETC(msg, afi);
+       STREAM_GETC(msg, type);
+       STREAM_GETW(msg, instance);
 
-       if (type == 0 || type >= ZEBRA_ROUTE_MAX)
+       if (afi == 0 || afi > AFI_MAX) {
+               zlog_warn("%s: Specified afi %d does not exist",
+                         __PRETTY_FUNCTION__, afi);
                return;
+       }
+
+       if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
+               zlog_warn("%s: Specified Route Type %d does not exist",
+                         __PRETTY_FUNCTION__, type);
+               return;
+       }
 
        /*
         * NOTE: no need to withdraw the previously advertised routes. The
@@ -312,17 +318,18 @@ void zebra_redistribute_delete(int command, struct zserv *client, int length,
                redist_del_instance(&client->mi_redist[afi][type], instance);
        else
                vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
+
+stream_failure:
+       return;
 }
 
-void zebra_redistribute_default_add(int command, struct zserv *client,
-                                   int length, struct zebra_vrf *zvrf)
+void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
 {
        vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
        zebra_redistribute_default(client, zvrf_id(zvrf));
 }
 
-void zebra_redistribute_default_delete(int command, struct zserv *client,
-                                      int length, struct zebra_vrf *zvrf)
+void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
 {
        vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
 }
@@ -503,84 +510,62 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
        struct route_entry *same;
        struct prefix p;
        route_map_result_t ret = RMAP_MATCH;
+       afi_t afi;
 
+       afi = family2afi(rn->p.family);
        if (rmap_name)
                ret = zebra_import_table_route_map_check(
-                       AFI_IP, re->type, &rn->p, re->nexthop, re->vrf_id,
+                       afi, re->type, &rn->p, re->ng.nexthop, re->vrf_id,
                        re->tag, rmap_name);
 
-       if (ret == RMAP_MATCH) {
-               if (rn->p.family == AF_INET) {
-                       p.family = AF_INET;
-                       p.prefixlen = rn->p.prefixlen;
-                       p.u.prefix4 = rn->p.u.prefix4;
+       if (ret != RMAP_MATCH) {
+               zebra_del_import_table_entry(rn, re);
+               return 0;
+       }
 
-                       RNODE_FOREACH_RE(rn, same)
-                       {
-                               if (CHECK_FLAG(same->status,
-                                              ROUTE_ENTRY_REMOVED))
-                                       continue;
+       prefix_copy(&p, &rn->p);
 
-                               if (same->type == re->type
-                                   && same->instance == re->instance
-                                   && same->table == re->table
-                                   && same->type != ZEBRA_ROUTE_CONNECT)
-                                       break;
-                       }
+       RNODE_FOREACH_RE (rn, same) {
+               if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
+                       continue;
 
-                       if (same)
-                               zebra_del_import_table_entry(rn, same);
-
-
-                       if (re->nexthop_num == 1) {
-                               rib_add(AFI_IP, SAFI_UNICAST, re->vrf_id,
-                                       ZEBRA_ROUTE_TABLE, re->table, 0, &p,
-                                       NULL, re->nexthop,
-                                       zebrad.rtm_table_default,
-                                       re->metric, re->mtu,
-                                       zebra_import_table_distance[AFI_IP]
-                                                                  [re->table]);
-                       } else if (re->nexthop_num > 1) {
-                               newre = XCALLOC(MTYPE_RE,
-                                               sizeof(struct route_entry));
-                               newre->type = ZEBRA_ROUTE_TABLE;
-                               newre->distance =
-                                       zebra_import_table_distance[AFI_IP]
-                                                                  [re->table];
-                               newre->flags = re->flags;
-                               newre->metric = re->metric;
-                               newre->mtu = re->mtu;
-                               newre->table = zebrad.rtm_table_default;
-                               newre->nexthop_num = 0;
-                               newre->uptime = time(NULL);
-                               newre->instance = re->table;
-                               route_entry_copy_nexthops(newre, re->nexthop);
-
-                               rib_add_multipath(AFI_IP, SAFI_UNICAST, &p,
-                                                 NULL, newre);
-                       }
-               }
-       } else {
-               zebra_del_import_table_entry(rn, re);
+               if (same->type == re->type && same->instance == re->instance
+                   && same->table == re->table
+                   && same->type != ZEBRA_ROUTE_CONNECT)
+                       break;
        }
-       /* DD: Add IPv6 code */
+
+       if (same)
+               zebra_del_import_table_entry(rn, same);
+
+       newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
+       newre->type = ZEBRA_ROUTE_TABLE;
+       newre->distance = zebra_import_table_distance[afi][re->table];
+       newre->flags = re->flags;
+       newre->metric = re->metric;
+       newre->mtu = re->mtu;
+       newre->table = zebrad.rtm_table_default;
+       newre->nexthop_num = 0;
+       newre->uptime = time(NULL);
+       newre->instance = re->table;
+       route_entry_copy_nexthops(newre, re->ng.nexthop);
+
+       rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
+
        return 0;
 }
 
 int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
 {
        struct prefix p;
+       afi_t afi;
 
-       if (rn->p.family == AF_INET) {
-               p.family = AF_INET;
-               p.prefixlen = rn->p.prefixlen;
-               p.u.prefix4 = rn->p.u.prefix4;
+       afi = family2afi(rn->p.family);
+       prefix_copy(&p, &rn->p);
 
-               rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
-                          re->table, re->flags, &p, NULL, NULL,
-                          zebrad.rtm_table_default, re->metric);
-       }
-       /* DD: Add IPv6 code */
+       rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
+                  re->flags, &p, NULL, re->ng.nexthop,
+                  zebrad.rtm_table_default, re->metric, false, NULL);
 
        return 0;
 }
@@ -639,8 +624,7 @@ int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance,
                if (!rn->info)
                        continue;
 
-               RNODE_FOREACH_RE(rn, re)
-               {
+               RNODE_FOREACH_RE (rn, re) {
                        if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
                                continue;
                        break;
@@ -670,28 +654,25 @@ int zebra_import_table_config(struct vty *vty)
 
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
-                       if (is_zebra_import_table_enabled(afi, i)) {
-                               if (zebra_import_table_distance[afi][i]
-                                   != ZEBRA_TABLE_DISTANCE_DEFAULT) {
-                                       vty_out(vty,
-                                               "%s import-table %d distance %d",
-                                               afi_str[afi], i,
-                                               zebra_import_table_distance[afi]
-                                                                          [i]);
-                               } else {
-                                       vty_out(vty, "%s import-table %d",
-                                               afi_str[afi], i);
-                               }
-
-                               rmap_name = zebra_get_import_table_route_map(
-                                       afi, i);
-                               if (rmap_name)
-                                       vty_out(vty, " route-map %s",
-                                               rmap_name);
+                       if (!is_zebra_import_table_enabled(afi, i))
+                               continue;
 
-                               vty_out(vty, "\n");
-                               write = 1;
+                       if (zebra_import_table_distance[afi][i]
+                           != ZEBRA_TABLE_DISTANCE_DEFAULT) {
+                               vty_out(vty, "%s import-table %d distance %d",
+                                       afi_str[afi], i,
+                                       zebra_import_table_distance[afi][i]);
+                       } else {
+                               vty_out(vty, "%s import-table %d", afi_str[afi],
+                                       i);
                        }
+
+                       rmap_name = zebra_get_import_table_route_map(afi, i);
+                       if (rmap_name)
+                               vty_out(vty, " route-map %s", rmap_name);
+
+                       vty_out(vty, "\n");
+                       write = 1;
                }
        }
 
@@ -709,42 +690,39 @@ void zebra_import_table_rm_update()
 
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
-                       if (is_zebra_import_table_enabled(afi, i)) {
-                               rmap_name = zebra_get_import_table_route_map(
-                                       afi, i);
-                               if (!rmap_name)
-                                       return;
-
-                               table = zebra_vrf_other_route_table(
-                                       afi, i, VRF_DEFAULT);
-                               for (rn = route_top(table); rn;
-                                    rn = route_next(rn)) {
-                                       /* For each entry in the non-default
-                                        * routing table,
-                                        * add the entry in the main table
-                                        */
-                                       if (!rn->info)
-                                               continue;
+                       if (!is_zebra_import_table_enabled(afi, i))
+                               continue;
 
-                                       RNODE_FOREACH_RE(rn, re)
-                                       {
-                                               if (CHECK_FLAG(
-                                                           re->status,
-                                                           ROUTE_ENTRY_REMOVED))
-                                                       continue;
-                                               break;
-                                       }
+                       rmap_name = zebra_get_import_table_route_map(afi, i);
+                       if (!rmap_name)
+                               return;
+
+                       table = zebra_vrf_other_route_table(afi, i,
+                                                           VRF_DEFAULT);
+                       for (rn = route_top(table); rn; rn = route_next(rn)) {
+                               /* For each entry in the non-default
+                                * routing table,
+                                * add the entry in the main table
+                                */
+                               if (!rn->info)
+                                       continue;
 
-                                       if (!re)
+                               RNODE_FOREACH_RE (rn, re) {
+                                       if (CHECK_FLAG(re->status,
+                                                      ROUTE_ENTRY_REMOVED))
                                                continue;
-
-                                       if (((afi == AFI_IP)
-                                            && (rn->p.family == AF_INET))
-                                           || ((afi == AFI_IP6)
-                                               && (rn->p.family == AF_INET6)))
-                                               zebra_add_import_table_entry(
-                                                       rn, re, rmap_name);
+                                       break;
                                }
+
+                               if (!re)
+                                       continue;
+
+                               if (((afi == AFI_IP)
+                                    && (rn->p.family == AF_INET))
+                                   || ((afi == AFI_IP6)
+                                       && (rn->p.family == AF_INET6)))
+                                       zebra_add_import_table_entry(rn, re,
+                                                                    rmap_name);
                        }
                }
        }