]> git.proxmox.com Git - mirror_frr.git/blobdiff - ripd/ripd.c
Merge pull request #5186 from opensourcerouting/nb-cbs-reorg
[mirror_frr.git] / ripd / ripd.c
index e0ff0430f81a4728cbe5524754975a60bdd0ed45..ec0770ef3d7d835441ff5da0b81c4edc621b0f9c 100644 (file)
 #include "if_rmap.h"
 #include "plist.h"
 #include "distribute.h"
+#ifdef CRYPTO_INTERNAL
 #include "md5.h"
+#endif
 #include "keychain.h"
 #include "privs.h"
 #include "lib_errors.h"
 #include "northbound_cli.h"
 
 #include "ripd/ripd.h"
+#include "ripd/rip_nb.h"
 #include "ripd/rip_debug.h"
 #include "ripd/rip_errors.h"
 #include "ripd/rip_interface.h"
@@ -870,7 +873,11 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from,
        struct rip_md5_data *md5data;
        struct keychain *keychain;
        struct key *key;
+#ifdef CRYPTO_OPENSSL
+       EVP_MD_CTX *ctx;
+#elif CRYPTO_INTERNAL
        MD5_CTX ctx;
+#endif
        uint8_t digest[RIP_AUTH_MD5_SIZE];
        uint16_t packet_len;
        char auth_str[RIP_AUTH_MD5_SIZE] = {};
@@ -934,11 +941,21 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from,
                return 0;
 
        /* MD5 digest authentication. */
+#ifdef CRYPTO_OPENSSL
+       unsigned int md5_size = RIP_AUTH_MD5_SIZE;
+       ctx = EVP_MD_CTX_new();
+       EVP_DigestInit(ctx, EVP_md5());
+       EVP_DigestUpdate(ctx, packet, packet_len + RIP_HEADER_SIZE);
+       EVP_DigestUpdate(ctx, auth_str, RIP_AUTH_MD5_SIZE);
+       EVP_DigestFinal(ctx, digest, &md5_size);
+       EVP_MD_CTX_free(ctx);
+#elif CRYPTO_INTERNAL
        memset(&ctx, 0, sizeof(ctx));
        MD5Init(&ctx);
        MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE);
        MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
        MD5Final(digest, &ctx);
+#endif
 
        if (memcmp(md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0)
                return packet_len;
@@ -1063,7 +1080,11 @@ static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri,
                             size_t doff, char *auth_str, int authlen)
 {
        unsigned long len;
+#ifdef CRYPTO_OPENSSL
+       EVP_MD_CTX *ctx;
+#elif CRYPTO_INTERNAL
        MD5_CTX ctx;
+#endif
        unsigned char digest[RIP_AUTH_MD5_SIZE];
 
        /* Make it sure this interface is configured as MD5
@@ -1092,11 +1113,21 @@ static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri,
        stream_putw(s, RIP_AUTH_DATA);
 
        /* Generate a digest for the RIP packet. */
+#ifdef CRYPTO_OPENSSL
+       unsigned int md5_size = RIP_AUTH_MD5_SIZE;
+       ctx = EVP_MD_CTX_new();
+       EVP_DigestInit(ctx, EVP_md5());
+       EVP_DigestUpdate(ctx, STREAM_DATA(s), stream_get_endp(s));
+       EVP_DigestUpdate(ctx, auth_str, RIP_AUTH_MD5_SIZE);
+       EVP_DigestFinal(ctx, digest, &md5_size);
+       EVP_MD_CTX_free(ctx);
+#elif CRYPTO_INTERNAL
        memset(&ctx, 0, sizeof(ctx));
        MD5Init(&ctx);
        MD5Update(&ctx, STREAM_DATA(s), stream_get_endp(s));
        MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE);
        MD5Final(digest, &ctx);
+#endif
 
        /* Copy the digest to the packet. */
        stream_write(s, digest, RIP_AUTH_MD5_SIZE);
@@ -1365,7 +1396,7 @@ int rip_create_socket(struct vrf *vrf)
        /* Make datagram socket. */
        if (vrf->vrf_id != VRF_DEFAULT)
                vrf_dev = vrf->name;
-       frr_elevate_privs(&ripd_privs) {
+       frr_with_privs(&ripd_privs) {
                sock = vrf_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, vrf->vrf_id,
                                  vrf_dev);
                if (sock < 0) {
@@ -1385,7 +1416,7 @@ int rip_create_socket(struct vrf *vrf)
 #endif
        setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF);
 
-       frr_elevate_privs(&ripd_privs) {
+       frr_with_privs(&ripd_privs) {
                if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
                    < 0) {
                        zlog_err("%s: Can't bind socket %d to %s port %d: %s",
@@ -3611,6 +3642,37 @@ static int rip_vrf_enable(struct vrf *vrf)
        int socket;
 
        rip = rip_lookup_by_vrf_name(vrf->name);
+       if (!rip) {
+               char *old_vrf_name = NULL;
+
+               rip = (struct rip *)vrf->info;
+               if (!rip)
+                       return 0;
+               /* update vrf name */
+               if (rip->vrf_name)
+                       old_vrf_name = rip->vrf_name;
+               rip->vrf_name = XSTRDUP(MTYPE_RIP_VRF_NAME, vrf->name);
+               /*
+                * HACK: Change the RIP VRF in the running configuration directly,
+                * bypassing the northbound layer. This is necessary to avoid deleting
+                * the RIP and readding it in the new VRF, which would have
+                * several implications.
+                */
+               if (yang_module_find("frr-ripd") && old_vrf_name) {
+                       struct lyd_node *rip_dnode;
+
+                       rip_dnode = yang_dnode_get(
+                               running_config->dnode,
+                               "/frr-ripd:ripd/instance[vrf='%s']/vrf",
+                               old_vrf_name);
+                       if (rip_dnode) {
+                               yang_dnode_change_leaf(rip_dnode, vrf->name);
+                               running_config->version++;
+                       }
+               }
+               if (old_vrf_name)
+                       XFREE(MTYPE_RIP_VRF_NAME, old_vrf_name);
+       }
        if (!rip || rip->enabled)
                return 0;
 
@@ -3652,7 +3714,7 @@ static int rip_vrf_disable(struct vrf *vrf)
 void rip_vrf_init(void)
 {
        vrf_init(rip_vrf_new, rip_vrf_enable, rip_vrf_disable, rip_vrf_delete,
-                NULL);
+                rip_vrf_enable);
 }
 
 void rip_vrf_terminate(void)