]> git.proxmox.com Git - mirror_frr.git/blobdiff - ripngd/ripngd.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ripngd / ripngd.c
index 27cffd43219602386d64458c60b5df6f0f101f7b..f01371f41ebb4a5b6df82600436b79abc6098bd8 100644 (file)
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* RIPng daemon
  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -61,7 +46,7 @@ void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
 static void ripng_instance_enable(struct ripng *ripng, struct vrf *vrf,
                                  int sock);
 static void ripng_instance_disable(struct ripng *ripng);
-int ripng_triggered_update(struct thread *);
+static void ripng_triggered_update(struct thread *);
 static void ripng_if_rmap_update(struct if_rmap_ctx *ctx,
                                 struct if_rmap *if_rmap);
 
@@ -196,7 +181,7 @@ int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to,
                zlog_debug("  send packet size %d", bufsize);
        }
 
-       memset(&addr, 0, sizeof(struct sockaddr_in6));
+       memset(&addr, 0, sizeof(addr));
        addr.sin6_family = AF_INET6;
 #ifdef SIN6_LEN
        addr.sin6_len = sizeof(struct sockaddr_in6);
@@ -217,7 +202,7 @@ int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to,
        msg.msg_namelen = sizeof(struct sockaddr_in6);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
-       msg.msg_control = (void *)adata;
+       msg.msg_control = adata;
        msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
 
        iov.iov_base = buf;
@@ -259,7 +244,7 @@ static int ripng_recv_packet(int sock, uint8_t *buf, int bufsize,
        struct cmsghdr *cmsgptr;
        struct in6_addr dst = {.s6_addr = {0}};
 
-       memset(&dst, 0, sizeof(struct in6_addr));
+       memset(&dst, 0, sizeof(dst));
 
        /* Ancillary data.  This store cmsghdr and in6_pktinfo.  But at this
           point I can't determine size of cmsghdr */
@@ -423,7 +408,7 @@ static int ripng_lladdr_check(struct interface *ifp, struct in6_addr *addr)
 }
 
 /* RIPng route garbage collect timer. */
-static int ripng_garbage_collect(struct thread *t)
+static void ripng_garbage_collect(struct thread *t)
 {
        struct ripng_info *rinfo;
        struct agg_node *rp;
@@ -431,7 +416,7 @@ static int ripng_garbage_collect(struct thread *t)
        rinfo = THREAD_ARG(t);
 
        /* Off timeout timer. */
-       RIPNG_TIMER_OFF(rinfo->t_timeout);
+       THREAD_OFF(rinfo->t_timeout);
 
        /* Get route_node pointer. */
        rp = rinfo->rp;
@@ -445,8 +430,6 @@ static int ripng_garbage_collect(struct thread *t)
 
        /* Free RIPng routing information. */
        ripng_info_free(rinfo);
-
-       return 0;
 }
 
 static void ripng_timeout_update(struct ripng *ripng, struct ripng_info *rinfo);
@@ -520,14 +503,14 @@ struct ripng_info *ripng_ecmp_replace(struct ripng *ripng,
        /* Re-use the first entry, and delete the others. */
        for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
                if (tmp_rinfo != rinfo) {
-                       RIPNG_TIMER_OFF(tmp_rinfo->t_timeout);
-                       RIPNG_TIMER_OFF(tmp_rinfo->t_garbage_collect);
+                       THREAD_OFF(tmp_rinfo->t_timeout);
+                       THREAD_OFF(tmp_rinfo->t_garbage_collect);
                        list_delete_node(list, node);
                        ripng_info_free(tmp_rinfo);
                }
 
-       RIPNG_TIMER_OFF(rinfo->t_timeout);
-       RIPNG_TIMER_OFF(rinfo->t_garbage_collect);
+       THREAD_OFF(rinfo->t_timeout);
+       THREAD_OFF(rinfo->t_garbage_collect);
        memcpy(rinfo, rinfo_new, sizeof(struct ripng_info));
 
        if (ripng_route_rte(rinfo)) {
@@ -559,7 +542,7 @@ struct ripng_info *ripng_ecmp_delete(struct ripng *ripng,
        struct agg_node *rp = rinfo->rp;
        struct list *list = (struct list *)rp->info;
 
-       RIPNG_TIMER_OFF(rinfo->t_timeout);
+       THREAD_OFF(rinfo->t_timeout);
 
        if (rinfo->metric != RIPNG_METRIC_INFINITY)
                ripng_aggregate_decrement(rp, rinfo);
@@ -567,7 +550,7 @@ struct ripng_info *ripng_ecmp_delete(struct ripng *ripng,
        if (listcount(list) > 1) {
                /* Some other ECMP entries still exist. Just delete this entry.
                 */
-               RIPNG_TIMER_OFF(rinfo->t_garbage_collect);
+               THREAD_OFF(rinfo->t_garbage_collect);
                listnode_delete(list, rinfo);
                if (ripng_route_rte(rinfo)
                    && CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB))
@@ -602,20 +585,18 @@ struct ripng_info *ripng_ecmp_delete(struct ripng *ripng,
 }
 
 /* Timeout RIPng routes. */
-static int ripng_timeout(struct thread *t)
+static void ripng_timeout(struct thread *t)
 {
        struct ripng_info *rinfo = THREAD_ARG(t);
        struct ripng *ripng = ripng_info_get_instance(rinfo);
 
        ripng_ecmp_delete(ripng, rinfo);
-
-       return 0;
 }
 
 static void ripng_timeout_update(struct ripng *ripng, struct ripng_info *rinfo)
 {
        if (rinfo->metric != RIPNG_METRIC_INFINITY) {
-               RIPNG_TIMER_OFF(rinfo->t_timeout);
+               THREAD_OFF(rinfo->t_timeout);
                thread_add_timer(master, ripng_timeout, rinfo,
                                 ripng->timeout_time, &rinfo->t_timeout);
        }
@@ -944,7 +925,7 @@ void ripng_redistribute_add(struct ripng *ripng, int type, int sub_type,
 
        rp = agg_node_get(ripng->table, (struct prefix *)p);
 
-       memset(&newinfo, 0, sizeof(struct ripng_info));
+       memset(&newinfo, 0, sizeof(newinfo));
        newinfo.type = type;
        newinfo.sub_type = sub_type;
        newinfo.ifindex = ifindex;
@@ -1026,7 +1007,7 @@ void ripng_redistribute_delete(struct ripng *ripng, int type, int sub_type,
                                RIPNG_TIMER_ON(rinfo->t_garbage_collect,
                                               ripng_garbage_collect,
                                               ripng->garbage_time);
-                               RIPNG_TIMER_OFF(rinfo->t_timeout);
+                               THREAD_OFF(rinfo->t_timeout);
 
                                /* Aggregate count decrement. */
                                ripng_aggregate_decrement(rp, rinfo);
@@ -1065,7 +1046,7 @@ void ripng_redistribute_withdraw(struct ripng *ripng, int type)
                                RIPNG_TIMER_ON(rinfo->t_garbage_collect,
                                               ripng_garbage_collect,
                                               ripng->garbage_time);
-                               RIPNG_TIMER_OFF(rinfo->t_timeout);
+                               THREAD_OFF(rinfo->t_timeout);
 
                                /* Aggregate count decrement. */
                                ripng_aggregate_decrement(rp, rinfo);
@@ -1149,7 +1130,7 @@ static void ripng_response_process(struct ripng_packet *packet, int size,
        ripng_peer_update(ripng, from, packet->version);
 
        /* Reset nexthop. */
-       memset(&nexthop, 0, sizeof(struct ripng_nexthop));
+       memset(&nexthop, 0, sizeof(nexthop));
        nexthop.flag = RIPNG_NEXTHOP_UNSPEC;
 
        /* Set RTE pointer. */
@@ -1276,7 +1257,7 @@ static void ripng_request_process(struct ripng_packet *packet, int size,
                   field.  Once all the entries have been filled in, change the
                   command from Request to Response and send the datagram back
                   to the requestor. */
-               memset(&p, 0, sizeof(struct prefix_ipv6));
+               memset(&p, 0, sizeof(p));
                p.family = AF_INET6;
 
                for (; ((caddr_t)rte) < lim; rte++) {
@@ -1301,7 +1282,7 @@ static void ripng_request_process(struct ripng_packet *packet, int size,
 }
 
 /* First entry point of reading RIPng packet. */
-static int ripng_read(struct thread *thread)
+static void ripng_read(struct thread *thread)
 {
        struct ripng *ripng = THREAD_ARG(thread);
        int len;
@@ -1330,7 +1311,7 @@ static int ripng_read(struct thread *thread)
        if (len < 0) {
                zlog_warn("RIPng recvfrom failed (VRF %s): %s.",
                          ripng->vrf_name, safe_strerror(errno));
-               return len;
+               return;
        }
 
        /* Check RTE boundary.  RTE size (Packet length - RIPng header size
@@ -1339,7 +1320,7 @@ static int ripng_read(struct thread *thread)
                zlog_warn("RIPng invalid packet size %d from %pI6 (VRF %s)",
                          len, &from.sin6_addr, ripng->vrf_name);
                ripng_peer_bad_packet(ripng, &from);
-               return 0;
+               return;
        }
 
        packet = (struct ripng_packet *)STREAM_DATA(ripng->ibuf);
@@ -1361,7 +1342,7 @@ static int ripng_read(struct thread *thread)
                zlog_warn(
                        "RIPng packet comes from unknown interface %d (VRF %s)",
                        ifindex, ripng->vrf_name);
-               return 0;
+               return;
        }
 
        /* Packet version mismatch checking. */
@@ -1370,7 +1351,7 @@ static int ripng_read(struct thread *thread)
                        "RIPng packet version %d doesn't fit to my version %d (VRF %s)",
                        packet->version, ripng->version, ripng->vrf_name);
                ripng_peer_bad_packet(ripng, &from);
-               return 0;
+               return;
        }
 
        /* Process RIPng packet. */
@@ -1387,7 +1368,6 @@ static int ripng_read(struct thread *thread)
                ripng_peer_bad_packet(ripng, &from);
                break;
        }
-       return 0;
 }
 
 /* Walk down the RIPng routing table then clear changed flag. */
@@ -1410,7 +1390,7 @@ static void ripng_clear_changed_flag(struct ripng *ripng)
 
 /* Regular update of RIPng route.  Send all routing formation to RIPng
    enabled interface. */
-static int ripng_update(struct thread *t)
+static void ripng_update(struct thread *t)
 {
        struct ripng *ripng = THREAD_ARG(t);
        struct interface *ifp;
@@ -1450,17 +1430,15 @@ static int ripng_update(struct thread *t)
 
        /* Triggered updates may be suppressed if a regular update is due by
           the time the triggered update would be sent. */
-       thread_cancel(&ripng->t_triggered_interval);
+       THREAD_OFF(ripng->t_triggered_interval);
        ripng->trigger = 0;
 
        /* Reset flush event. */
        ripng_event(ripng, RIPNG_UPDATE_EVENT, 0);
-
-       return 0;
 }
 
 /* Triggered update interval timer. */
-static int ripng_triggered_interval(struct thread *t)
+static void ripng_triggered_interval(struct thread *t)
 {
        struct ripng *ripng = THREAD_ARG(t);
 
@@ -1468,11 +1446,10 @@ static int ripng_triggered_interval(struct thread *t)
                ripng->trigger = 0;
                ripng_triggered_update(t);
        }
-       return 0;
 }
 
 /* Execute triggered update. */
-int ripng_triggered_update(struct thread *t)
+void ripng_triggered_update(struct thread *t)
 {
        struct ripng *ripng = THREAD_ARG(t);
        struct interface *ifp;
@@ -1480,7 +1457,7 @@ int ripng_triggered_update(struct thread *t)
        int interval;
 
        /* Cancel interval timer. */
-       thread_cancel(&ripng->t_triggered_interval);
+       THREAD_OFF(ripng->t_triggered_interval);
        ripng->trigger = 0;
 
        /* Logging triggered update. */
@@ -1518,8 +1495,6 @@ int ripng_triggered_update(struct thread *t)
 
        thread_add_timer(master, ripng_triggered_interval, ripng, interval,
                         &ripng->t_triggered_interval);
-
-       return 0;
 }
 
 /* Write routing table entry to the stream and return next index of
@@ -1927,7 +1902,7 @@ void ripng_event(struct ripng *ripng, enum ripng_event event, int sock)
                                &ripng->t_read);
                break;
        case RIPNG_UPDATE_EVENT:
-               thread_cancel(&ripng->t_update);
+               THREAD_OFF(ripng->t_update);
 
                /* Update timer jitter. */
                jitter = ripng_update_jitter(ripng->update_time);
@@ -1943,7 +1918,8 @@ void ripng_event(struct ripng *ripng, enum ripng_event event, int sock)
                        thread_add_event(master, ripng_triggered_update, ripng,
                                         0, &ripng->t_triggered_update);
                break;
-       default:
+       case RIPNG_ZEBRA:
+       case RIPNG_REQUEST_EVENT:
                break;
        }
 }
@@ -2219,8 +2195,8 @@ void ripng_ecmp_disable(struct ripng *ripng)
                        /* Drop all other entries, except the first one. */
                        for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
                                if (tmp_rinfo != rinfo) {
-                                       RIPNG_TIMER_OFF(tmp_rinfo->t_timeout);
-                                       RIPNG_TIMER_OFF(
+                                       THREAD_OFF(tmp_rinfo->t_timeout);
+                                       THREAD_OFF(
                                                tmp_rinfo->t_garbage_collect);
                                        list_delete_node(list, node);
                                        ripng_info_free(tmp_rinfo);
@@ -2538,8 +2514,8 @@ static void ripng_instance_disable(struct ripng *ripng)
                                ripng_zebra_ipv6_delete(ripng, rp);
 
                        for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
-                               RIPNG_TIMER_OFF(rinfo->t_timeout);
-                               RIPNG_TIMER_OFF(rinfo->t_garbage_collect);
+                               THREAD_OFF(rinfo->t_timeout);
+                               THREAD_OFF(rinfo->t_garbage_collect);
                                ripng_info_free(rinfo);
                        }
                        list_delete(&list);
@@ -2558,12 +2534,12 @@ static void ripng_instance_disable(struct ripng *ripng)
        ripng_redistribute_disable(ripng);
 
        /* Cancel the RIPng timers */
-       RIPNG_TIMER_OFF(ripng->t_update);
-       RIPNG_TIMER_OFF(ripng->t_triggered_update);
-       RIPNG_TIMER_OFF(ripng->t_triggered_interval);
+       THREAD_OFF(ripng->t_update);
+       THREAD_OFF(ripng->t_triggered_update);
+       THREAD_OFF(ripng->t_triggered_interval);
 
        /* Cancel the read thread */
-       thread_cancel(&ripng->t_read);
+       THREAD_OFF(ripng->t_read);
 
        /* Close the RIPng socket */
        if (ripng->sock >= 0) {
@@ -2591,10 +2567,17 @@ static int ripng_vrf_new(struct vrf *vrf)
 
 static int ripng_vrf_delete(struct vrf *vrf)
 {
+       struct ripng *ripng;
+
        if (IS_RIPNG_DEBUG_EVENT)
                zlog_debug("%s: VRF deleted: %s(%u)", __func__, vrf->name,
                           vrf->vrf_id);
 
+       ripng = ripng_lookup_by_vrf_name(vrf->name);
+       if (!ripng)
+               return 0;
+
+       ripng_clean(ripng);
        return 0;
 }