]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: irdp: manage separate IRDP struct
authorDavid Lamparter <equinox@opensourcerouting.org>
Sun, 6 Aug 2017 06:57:42 +0000 (08:57 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Tue, 15 Aug 2017 11:26:03 +0000 (13:26 +0200)
This allocates the per-interface IRDP data as needed; so the pointer in
zebra_if is now really opaque.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
zebra/irdp_interface.c
zebra/irdp_main.c
zebra/irdp_packet.c

index 032090adf2a93b0ba3e6fa12b3625be27785646d..3465bdebbfbda3243173af39f2fec884a1e797d7 100644 (file)
 
 extern int irdp_sock;
 
+DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data")
+
+static struct irdp_interface *irdp_if_get(struct interface *ifp)
+{
+       struct zebra_if *zi = ifp->info;
+       if (!zi->irdp)
+               zi->irdp = XCALLOC(MTYPE_IRDP_IF, sizeof(*zi->irdp));
+       return zi->irdp;
+}
+
+static int irdp_if_delete(struct interface *ifp)
+{
+       struct zebra_if *zi = ifp->info;
+       if (!zi)
+               return 0;
+       XFREE(MTYPE_IRDP_IF, zi->irdp);
+       return 0;
+}
+
 static const char *inet_2a(u_int32_t a, char *b)
 {
        sprintf(b, "%u.%u.%u.%u", (a)&0xFF, (a >> 8) & 0xFF, (a >> 16) & 0xFF,
@@ -117,10 +136,13 @@ static int if_group(struct interface *ifp, int sock, u_int32_t group,
 static int if_add_group(struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        int ret;
        char b1[INET_ADDRSTRLEN];
 
+       if (!irdp)
+               return -1;
+
        ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP);
        if (ret < 0) {
                return ret;
@@ -135,10 +157,13 @@ static int if_add_group(struct interface *ifp)
 static int if_drop_group(struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        int ret;
        char b1[INET_ADDRSTRLEN];
 
+       if (!irdp)
+               return -1;
+
        ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP,
                       IP_DROP_MEMBERSHIP);
        if (ret < 0)
@@ -150,11 +175,8 @@ static int if_drop_group(struct interface *ifp)
        return 0;
 }
 
-static void if_set_defaults(struct interface *ifp)
+static void if_set_defaults(struct irdp_interface *irdp)
 {
-       struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
-
        irdp->MaxAdvertInterval = IRDP_MAXADVERTINTERVAL;
        irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL;
        irdp->Preference = IRDP_PREFERENCE;
@@ -176,11 +198,13 @@ static void irdp_if_start(struct interface *ifp, int multicast,
                          int set_defaults)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        struct listnode *node;
        struct connected *ifc;
        u_int32_t timer, seed;
 
+       assert(irdp);
+
        if (irdp->flags & IF_ACTIVE) {
                zlog_warn("IRDP: Interface is already active %s", ifp->name);
                return;
@@ -215,7 +239,7 @@ static void irdp_if_start(struct interface *ifp, int multicast,
        }
 
        if (set_defaults)
-               if_set_defaults(ifp);
+               if_set_defaults(irdp);
 
        irdp->irdp_sent = 0;
 
@@ -254,7 +278,7 @@ static void irdp_if_start(struct interface *ifp, int multicast,
 static void irdp_if_stop(struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
 
        if (irdp == NULL) {
                zlog_warn("Interface %s structure is NULL", ifp->name);
@@ -281,8 +305,10 @@ static void irdp_if_stop(struct interface *ifp)
 static void irdp_if_shutdown(struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
 
+       if (!irdp)
+               return;
        if (irdp->flags & IF_SHUTDOWN) {
                zlog_warn("IRDP: Interface is already shutdown %s", ifp->name);
                return;
@@ -300,8 +326,7 @@ static void irdp_if_shutdown(struct interface *ifp)
 
 static void irdp_if_no_shutdown(struct interface *ifp)
 {
-       struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        if (!(irdp->flags & IF_SHUTDOWN)) {
                zlog_warn("IRDP: Interface is not shutdown %s", ifp->name);
@@ -319,11 +344,14 @@ static void irdp_if_no_shutdown(struct interface *ifp)
 int irdp_config_write(struct vty *vty, struct interface *ifp)
 {
        struct zebra_if *zi = ifp->info;
-       struct irdp_interface *irdp = &zi->irdp;
+       struct irdp_interface *irdp = zi->irdp;
        struct Adv *adv;
        struct listnode *node;
        char b1[INET_ADDRSTRLEN];
 
+       if (!irdp)
+               return 0;
+
        if (irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) {
 
                if (irdp->flags & IF_SHUTDOWN)
@@ -360,6 +388,7 @@ DEFUN (ip_irdp_multicast,
        "Use multicast mode\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
+       irdp_if_get(ifp);
 
        irdp_if_start(ifp, TRUE, TRUE);
        return CMD_SUCCESS;
@@ -373,6 +402,7 @@ DEFUN (ip_irdp_broadcast,
        "Use broadcast mode\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
+       irdp_if_get(ifp);
 
        irdp_if_start(ifp, FALSE, TRUE);
        return CMD_SUCCESS;
@@ -428,11 +458,7 @@ DEFUN (ip_irdp_holdtime,
 {
        int idx_number = 3;
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        irdp->Lifetime = atoi(argv[idx_number]->arg);
        return CMD_SUCCESS;
@@ -448,11 +474,7 @@ DEFUN (ip_irdp_minadvertinterval,
 {
        int idx_number = 3;
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) {
                irdp->MinAdvertInterval = atoi(argv[idx_number]->arg);
@@ -475,11 +497,7 @@ DEFUN (ip_irdp_maxadvertinterval,
 {
        int idx_number = 3;
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) {
                irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg);
@@ -507,11 +525,7 @@ DEFUN (ip_irdp_preference,
 {
        int idx_number = 3;
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        irdp->Preference = atoi(argv[idx_number]->arg);
        return CMD_SUCCESS;
@@ -530,17 +544,13 @@ DEFUN (ip_irdp_address_preference,
        int idx_ipv4 = 3;
        int idx_number = 5;
        VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct irdp_interface *irdp = irdp_if_get(ifp);
        struct listnode *node;
        struct in_addr ip;
        int pref;
        int ret;
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
        struct Adv *adv;
 
-       zi = ifp->info;
-       irdp = &zi->irdp;
-
        ret = inet_aton(argv[idx_ipv4]->arg, &ip);
        if (!ret)
                return CMD_WARNING_CONFIG_FAILED;
@@ -572,16 +582,12 @@ DEFUN (no_ip_irdp_address_preference,
 {
        int idx_ipv4 = 4;
        VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct irdp_interface *irdp = irdp_if_get(ifp);
        struct listnode *node, *nnode;
        struct in_addr ip;
        int ret;
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
        struct Adv *adv;
 
-       zi = ifp->info;
-       irdp = &zi->irdp;
-
        ret = inet_aton(argv[idx_ipv4]->arg, &ip);
        if (!ret)
                return CMD_WARNING_CONFIG_FAILED;
@@ -605,11 +611,7 @@ DEFUN (ip_irdp_debug_messages,
        "Enable debugging for IRDP messages\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        irdp->flags |= IF_DEBUG_MESSAGES;
 
@@ -625,11 +627,7 @@ DEFUN (ip_irdp_debug_misc,
        "Enable debugging for miscellaneous IRDP events\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        irdp->flags |= IF_DEBUG_MISC;
 
@@ -645,11 +643,7 @@ DEFUN (ip_irdp_debug_packet,
        "Enable debugging for IRDP packets\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        irdp->flags |= IF_DEBUG_PACKET;
 
@@ -666,11 +660,7 @@ DEFUN (ip_irdp_debug_disable,
        "Disable debugging for all IRDP events\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zi;
-       struct irdp_interface *irdp;
-
-       zi = ifp->info;
-       irdp = &zi->irdp;
+       struct irdp_interface *irdp = irdp_if_get(ifp);
 
        irdp->flags &= ~IF_DEBUG_PACKET;
        irdp->flags &= ~IF_DEBUG_MESSAGES;
@@ -682,6 +672,7 @@ DEFUN (ip_irdp_debug_disable,
 void irdp_if_init()
 {
        hook_register(zebra_if_config_wr, irdp_config_write);
+       hook_register(if_del, irdp_if_delete);
 
        install_element(INTERFACE_NODE, &ip_irdp_broadcast_cmd);
        install_element(INTERFACE_NODE, &ip_irdp_multicast_cmd);
index e463608af1f165d7b30eae41e1e6c311999b6215..73c6d8141aea6cb24ac83ae58e5a09edc147b7a5 100644 (file)
@@ -52,6 +52,7 @@
 #include "zclient.h"
 #include "thread.h"
 #include "privs.h"
+#include "libfrr.h"
 #include "zebra/interface.h"
 #include "zebra/rtadv.h"
 #include "zebra/rib.h"
@@ -143,7 +144,7 @@ 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;
@@ -175,11 +176,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;
 
+       if (!irdp)
+               return;
        if (!(ifp->flags & IFF_UP))
                return;
 
@@ -211,11 +214,14 @@ int irdp_send_thread(struct thread *t_advert)
        u_int32_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 +256,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,9 +288,12 @@ 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;
+       struct irdp_interface *irdp = zi->irdp;
        u_int32_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
           about DoS attacks here. */
@@ -317,7 +329,7 @@ static int irdp_finish(void)
 
                if (!zi)
                        continue;
-               irdp = &zi->irdp;
+               irdp = zi->irdp;
                if (!irdp)
                        continue;
 
@@ -326,6 +338,7 @@ static int irdp_finish(void)
                        irdp_advert_off(ifp);
                }
        }
+       return 0;
 }
 
 void irdp_init(void)
index 3bd093d97bfb9ea85d11e2f00efcc034ffa4efbe..a64eac2ea46c83cf7b60c2b5f1aa3b958a75d3c5 100644 (file)
@@ -84,7 +84,7 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
        if (!zi)
                return;
 
-       irdp = &zi->irdp;
+       irdp = zi->irdp;
        if (!irdp)
                return;
 
@@ -240,7 +240,7 @@ int irdp_read_raw(struct thread *r)
        if (!zi)
                return ret;
 
-       irdp = &zi->irdp;
+       irdp = zi->irdp;
        if (!irdp)
                return ret;