]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/irdp_main.c
isisd: implement the 'lsp-too-large' notification
[mirror_frr.git] / zebra / irdp_main.c
index 6220c9d81b1fda53083e053540568987058329f3..9300ba6034f888ad41980ebbfe049ad94e38d6fd 100644 (file)
  */
 
 /*
- * Thanks to Jens Låås at Swedish University of Agricultural Sciences
+ * Thanks to Jens Laas at Swedish University of Agricultural Sciences
  * for reviewing and tests.
  */
 
 
 #include <zebra.h>
 
-#ifdef HAVE_IRDP
-
 #include "if.h"
 #include "vty.h"
 #include "sockunion.h"
 #include "zclient.h"
 #include "thread.h"
 #include "privs.h"
+#include "libfrr.h"
+#include "lib_errors.h"
+#include "version.h"
 #include "zebra/interface.h"
 #include "zebra/rtadv.h"
 #include "zebra/rib.h"
 #include "zebra/zserv.h"
 #include "zebra/redistribute.h"
 #include "zebra/irdp.h"
+#include "zebra/zebra_errors.h"
 #include <netinet/ip_icmp.h>
 
 #include "checksum.h"
@@ -80,36 +82,32 @@ int irdp_sock_init(void)
        int save_errno;
        int sock;
 
-       if (zserv_privs.change(ZPRIVS_RAISE))
-               zlog_err("irdp_sock_init: could not raise privs, %s",
-                        safe_strerror(errno));
+       frr_elevate_privs(&zserv_privs) {
 
-       sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
-       save_errno = errno;
+               sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+               save_errno = errno;
 
-       if (zserv_privs.change(ZPRIVS_LOWER))
-               zlog_err("irdp_sock_init: could not lower privs, %s",
-                        safe_strerror(errno));
+       }
 
        if (sock < 0) {
-               zlog_warn("IRDP: can't create irdp socket %s",
-                         safe_strerror(save_errno));
+               flog_err_sys(EC_LIB_SOCKET, "IRDP: can't create irdp socket %s",
+                            safe_strerror(save_errno));
                return sock;
        };
 
        i = 1;
        ret = setsockopt(sock, IPPROTO_IP, IP_TTL, (void *)&i, sizeof(i));
        if (ret < 0) {
-               zlog_warn("IRDP: can't do irdp sockopt %s",
-                         safe_strerror(errno));
+               flog_err_sys(EC_LIB_SOCKET, "IRDP: can't do irdp sockopt %s",
+                            safe_strerror(errno));
                close(sock);
                return ret;
        };
 
        ret = setsockopt_ifindex(AF_INET, sock, 1);
        if (ret < 0) {
-               zlog_warn("IRDP: can't do irdp sockopt %s",
-                         safe_strerror(errno));
+               flog_err_sys(EC_LIB_SOCKET, "IRDP: can't do irdp sockopt %s",
+                            safe_strerror(errno));
                close(sock);
                return ret;
        };
@@ -143,10 +141,10 @@ static int make_advertisement_packet(struct interface *ifp, struct prefix *p,
                                     struct stream *s)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        int size;
        int pref;
-       u_int16_t checksum;
+       uint16_t checksum;
 
        pref = get_pref(irdp, p);
 
@@ -175,11 +173,13 @@ static int make_advertisement_packet(struct interface *ifp, struct prefix *p,
 static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        char buf[PREFIX_STRLEN];
-       u_int32_t dst;
-       u_int32_t ttl = 1;
+       uint32_t dst;
+       uint32_t ttl = 1;
 
+       if (!irdp)
+               return;
        if (!(ifp->flags & IFF_UP))
                return;
 
@@ -208,14 +208,17 @@ static void irdp_advertisement(struct interface *ifp, struct prefix *p)
 
 int irdp_send_thread(struct thread *t_advert)
 {
-       u_int32_t timer, tmp;
+       uint32_t timer, tmp;
        struct interface *ifp = THREAD_ARG(t_advert);
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        struct prefix *p;
        struct listnode *node, *nnode;
        struct connected *ifc;
 
+       if (!irdp)
+               return 0;
+
        irdp->flags &= ~IF_SOLICIT;
 
        if (ifp->connected)
@@ -250,12 +253,15 @@ int irdp_send_thread(struct thread *t_advert)
 void irdp_advert_off(struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        struct listnode *node, *nnode;
        int i;
        struct connected *ifc;
        struct prefix *p;
 
+       if (!irdp)
+               return;
+
        if (irdp->t_advertise)
                thread_cancel(irdp->t_advertise);
        irdp->t_advertise = NULL;
@@ -279,8 +285,11 @@ void irdp_advert_off(struct interface *ifp)
 void process_solicit(struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
-       u_int32_t timer;
+       struct irdp_interface *irdp = zi->irdp;
+       uint32_t timer;
+
+       if (!irdp)
+               return;
 
        /* When SOLICIT is active we reject further incoming solicits
           this keeps down the answering rate so we don't have think
@@ -301,31 +310,46 @@ void process_solicit(struct interface *ifp)
                         &irdp->t_advertise);
 }
 
-void irdp_finish()
+static int irdp_finish(void)
 {
        struct vrf *vrf;
-       struct listnode *node, *nnode;
        struct interface *ifp;
        struct zebra_if *zi;
        struct irdp_interface *irdp;
 
        zlog_info("IRDP: Received shutdown notification.");
 
-       RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id)
-       for (ALL_LIST_ELEMENTS(vrf->iflist, node, nnode, ifp)) {
-               zi = ifp->info;
+       RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
+               FOR_ALL_INTERFACES (vrf, ifp) {
+                       zi = ifp->info;
 
-               if (!zi)
-                       continue;
-               irdp = &zi->irdp;
-               if (!irdp)
-                       continue;
+                       if (!zi)
+                               continue;
+                       irdp = zi->irdp;
+                       if (!irdp)
+                               continue;
 
-               if (irdp->flags & IF_ACTIVE) {
-                       irdp->flags |= IF_SHUTDOWN;
-                       irdp_advert_off(ifp);
+                       if (irdp->flags & IF_ACTIVE) {
+                               irdp->flags |= IF_SHUTDOWN;
+                               irdp_advert_off(ifp);
+                       }
                }
-       }
+       return 0;
+}
+
+static int irdp_init(struct thread_master *master)
+{
+       irdp_if_init();
+
+       hook_register(frr_early_fini, irdp_finish);
+       return 0;
+}
+
+static int irdp_module_init(void)
+{
+       hook_register(frr_late_init, irdp_init);
+       return 0;
 }
 
-#endif /* HAVE_IRDP */
+FRR_MODULE_SETUP(.name = "zebra_irdp", .version = FRR_VERSION,
+                .description = "zebra IRDP module", .init = irdp_module_init, )